Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-10-25 09:40:10

0001 #ifndef DETECTOR_DESCRIPTION_CORE_DD_SOLID_H
0002 #define DETECTOR_DESCRIPTION_CORE_DD_SOLID_H
0003 
0004 #include <cstddef>
0005 #include <iosfwd>
0006 #include <memory>
0007 #include <vector>
0008 
0009 #include "DetectorDescription/Core/interface/DDTranslation.h"
0010 #include "DetectorDescription/Core/interface/DDBase.h"
0011 #include "DetectorDescription/Core/interface/DDName.h"
0012 #include "DetectorDescription/Core/interface/DDSolidShapes.h"
0013 #include "DetectorDescription/Core/interface/DDTransform.h"
0014 
0015 class DDSolid;
0016 
0017 namespace DDI {
0018   class BooleanSolid;
0019   class MultiUnion;
0020   class Reflection;
0021   class Solid;
0022 }  // namespace DDI
0023 struct DDSolidFactory;
0024 
0025 std::ostream& operator<<(std::ostream&, const DDSolid&);
0026 
0027 //! A DDSolid represents the shape of a part.
0028 /** An object of this class is a reference-object and thus is a lightweight
0029     class. It can be copied by value without having a large overhead.
0030     Assignment to the reference-object invalidates the object to which it was 
0031     referred.  Assignment also affects all other instances of this class which 
0032     were created using the same value of DDName. In fact, the value of DDName
0033     identifies a DDSolid uniquely.
0034     
0035     For further details concerning the usage of reference-objects refer
0036     to the documentation of DDLogicalPart.   
0037 
0038 */
0039 class DDSolid : public DDBase<DDName, std::unique_ptr<DDI::Solid>> {
0040   friend std::ostream& operator<<(std::ostream&, const DDSolid&);
0041   friend struct DDSolidFactory;
0042 
0043 public:
0044   //! Uninitialilzed solid reference-object; for further details on reference-objects see documentation of DDLogicalPart
0045   DDSolid(void);
0046 
0047   //! Creates a reference-object to a solid named \a name
0048   /** If the solid was not yet created using one of the solid generating factory 
0049       functions \c DDbox(), \c DDtub , ... this constructor creates a (default) 
0050       initialized reference object named \a name. It can be used as placeholder 
0051       everywhere and becomes a reference to a valid solid as soon as one of the 
0052       factory functions \c DDBox, ... has been called (using the same value for DDName).
0053       
0054       For further details concerning reference-objects refer to the documentation of DDLogicalPart.       
0055   */
0056   DDSolid(const DDName& name);
0057 
0058   //! Give the parameters of the solid
0059   const std::vector<double>& parameters(void) const;
0060 
0061   //! Returns the volume of the given solid (\b does \b not \b work \b with \b boolean \b soids \b !)
0062   double volume(void) const;
0063 
0064   //! The type of the solid
0065   DDSolidShape shape(void) const;
0066 
0067 private:
0068   DDSolid(const DDName&, std::unique_ptr<DDI::Solid>);
0069   DDSolid(const DDName&, DDSolidShape, const std::vector<double>&);
0070 };
0071 
0072 //! Interface to an Assembly
0073 /**
0074    The definition of an Assembly is
0075    the same as in Geant4.
0076 */
0077 class DDAssembly : public DDSolid {
0078 public:
0079   DDAssembly(const DDSolid& s);
0080   DDAssembly(void) = delete;
0081 };
0082 
0083 //! Interface to a Trapezoid
0084 /**
0085    The definition (parameters, local frame) of the Trapezoid is 
0086    the same than in Geant4.
0087 */
0088 class DDTrap : public DDSolid {
0089 public:
0090   DDTrap(const DDSolid& s);
0091   DDTrap(void) = delete;
0092 
0093   //! half of the z-Axis
0094   double halfZ(void) const;
0095   //! Polar angle of the line joining the centres of the faces at -/+pDz
0096   double theta(void) const;
0097   //! Azimuthal angle of the line joining the centres of the faces at -/+pDz
0098   double phi(void) const;
0099   //! Half-length along y of the face at -pDz
0100   double y1(void) const;
0101   //! Half-length along x of the side at y=-pDy1 of the face at -pDz
0102   double x1(void) const;
0103   //! Half-length along x of the side at y=+pDy1 of the face at -pDz
0104   double x2(void) const;
0105   //! Angle with respect to the y axis from the centre of the side at y=-pDy1 to the centre at y=+pDy1 of the face at -pDz
0106   double alpha1(void) const;
0107   //! Half-length along y of the face at +pDz
0108   double y2(void) const;
0109   //! Half-length along x of the side at y=-pDy2 of the face at +pDz
0110   double x3(void) const;
0111   //! Half-length along x of the side at y=+pDy2 of the face at +pDz
0112   double x4(void) const;
0113   //! Angle with respect to the y axis from the centre of the side at y=-pDy2 to the centre at y=+pDy2 of the face at +pDz
0114   double alpha2(void) const;
0115 };
0116 
0117 class DDPseudoTrap : public DDSolid {
0118 public:
0119   DDPseudoTrap(const DDSolid& s);
0120   DDPseudoTrap(void) = delete;
0121 
0122   //! half of the z-Axis
0123   double halfZ(void) const;
0124   //! half length along x on -z
0125   double x1(void) const;
0126   //! half length along x on +z
0127   double x2(void) const;
0128   //! half length along y on -z
0129   double y1(void) const;
0130   //! half length along y on +z
0131   double y2(void) const;
0132   //! radius of the cut-out (neg.) or rounding (pos.)
0133   double radius(void) const;
0134   //! true, if cut-out or rounding is on the -z side
0135   bool atMinusZ(void) const;
0136 };
0137 
0138 /// A truncated tube section
0139 class DDTruncTubs : public DDSolid {
0140 public:
0141   DDTruncTubs(const DDSolid& s);
0142   DDTruncTubs(void) = delete;
0143 
0144   //! half of the z-Axis
0145   double zHalf(void) const;
0146   //! inner radius
0147   double rIn(void) const;
0148   //! outer radius
0149   double rOut(void) const;
0150   //! angular start of the tube-section
0151   double startPhi(void) const;
0152   //! angular span of the tube-section
0153   double deltaPhi(void) const;
0154   //! truncation at begin of the tube-section
0155   double cutAtStart(void) const;
0156   //! truncation at end of the tube-section
0157   double cutAtDelta(void) const;
0158   //! true, if truncation is on the inner side of the tube-section
0159   bool cutInside(void) const;
0160 };
0161 
0162 //! Interface to a Box
0163 /**
0164    The definition (parameters, local frame) of the Box is 
0165    the same than in Geant4.
0166 */
0167 class DDBox : public DDSolid {
0168 public:
0169   DDBox(const DDSolid& s);
0170   DDBox(void) = delete;
0171 
0172   double halfX(void) const;
0173   double halfY(void) const;
0174   double halfZ(void) const;
0175 };
0176 
0177 /// This is simply a handle on the solid.
0178 class DDShapelessSolid : public DDSolid {
0179 public:
0180   DDShapelessSolid(const DDSolid& s);
0181   DDShapelessSolid(void) = delete;
0182 };
0183 
0184 class DDBooleanSolid : public DDSolid {
0185 public:
0186   DDBooleanSolid(const DDSolid& s);
0187   DDBooleanSolid(void) = delete;
0188 
0189   DDSolid solidA(void) const;
0190   DDSolid solidB(void) const;
0191   DDTranslation translation(void) const;
0192   DDRotation rotation(void) const;
0193 
0194 private:
0195   const DDI::BooleanSolid& boolean_;
0196 };
0197 
0198 class DDMultiUnionSolid : public DDSolid {
0199 public:
0200   DDMultiUnionSolid(const DDSolid& s);
0201   DDMultiUnionSolid(void) = delete;
0202 
0203   const std::vector<DDSolid>& solids(void) const;
0204   const std::vector<DDTranslation>& translations(void) const;
0205   const std::vector<DDRotation>& rotations(void) const;
0206 
0207 private:
0208   DDI::MultiUnion* union_;
0209 };
0210 
0211 /// Abstract class for DDPolycone and DDPolyhedra.  Basically a common member function.
0212 class DDPolySolid : public DDSolid {
0213 public:
0214   DDPolySolid(const DDSolid& s);
0215   DDPolySolid(void) = delete;
0216 
0217 protected:
0218   /// note defaults please.
0219   virtual std::vector<double> getVec(const size_t& which, const size_t& offset = 0, const size_t& nVecs = 1) const;
0220 };
0221 
0222 class DDPolycone : public DDPolySolid {
0223 public:
0224   DDPolycone(const DDSolid& s);
0225   DDPolycone(void) = delete;
0226 
0227   double startPhi(void) const;
0228   double deltaPhi(void) const;
0229   std::vector<double> zVec(void) const;
0230   std::vector<double> rVec(void) const;
0231   std::vector<double> rMinVec(void) const;
0232   std::vector<double> rMaxVec(void) const;
0233 };
0234 
0235 class DDPolyhedra : public DDPolySolid {
0236 public:
0237   DDPolyhedra(const DDSolid& s);
0238   DDPolyhedra(void) = delete;
0239 
0240   int sides(void) const;
0241   double startPhi(void) const;
0242   double deltaPhi(void) const;
0243   std::vector<double> zVec(void) const;
0244   std::vector<double> rVec(void) const;
0245   std::vector<double> rMinVec(void) const;
0246   std::vector<double> rMaxVec(void) const;
0247 };
0248 
0249 class DDExtrudedPolygon : public DDPolySolid {
0250 public:
0251   DDExtrudedPolygon(const DDSolid& s);
0252   DDExtrudedPolygon(void) = delete;
0253 
0254   std::vector<double> xVec(void) const;
0255   std::vector<double> yVec(void) const;
0256   std::vector<double> zVec(void) const;
0257   std::vector<double> zxVec(void) const;
0258   std::vector<double> zyVec(void) const;
0259   std::vector<double> zscaleVec(void) const;
0260 
0261 private:
0262   auto xyPointsSize(void) const -> std::size_t;
0263   auto zSectionsSize(void) const -> std::size_t;
0264 };
0265 
0266 class DDTubs : public DDSolid {
0267 public:
0268   DDTubs(const DDSolid& s);
0269   DDTubs(void) = delete;
0270 
0271   double zhalf(void) const;
0272   double rIn(void) const;
0273   double rOut(void) const;
0274   double startPhi(void) const;
0275   double deltaPhi(void) const;
0276 };
0277 
0278 class DDCutTubs : public DDSolid {
0279 public:
0280   DDCutTubs(const DDSolid& s);
0281   DDCutTubs(void) = delete;
0282 
0283   double zhalf(void) const;
0284   double rIn(void) const;
0285   double rOut(void) const;
0286   double startPhi(void) const;
0287   double deltaPhi(void) const;
0288   std::array<double, 3> lowNorm(void) const;
0289   std::array<double, 3> highNorm(void) const;
0290 };
0291 
0292 class DDCons : public DDSolid {
0293 public:
0294   DDCons(const DDSolid& s);
0295   DDCons(void) = delete;
0296 
0297   double zhalf(void) const;
0298   double rInMinusZ(void) const;
0299   double rOutMinusZ(void) const;
0300   double rInPlusZ(void) const;
0301   double rOutPlusZ(void) const;
0302   double phiFrom(void) const;
0303   double deltaPhi(void) const;
0304 };
0305 
0306 class DDTorus : public DDSolid {
0307 public:
0308   DDTorus(const DDSolid& s);
0309   DDTorus(void) = delete;
0310 
0311   double rMin(void) const;
0312   double rMax(void) const;
0313   double rTorus(void) const;
0314   double startPhi(void) const;
0315   double deltaPhi(void) const;
0316 };
0317 
0318 class DDUnion : public DDBooleanSolid {
0319 public:
0320   DDUnion(const DDSolid& s);
0321   DDUnion(void) = delete;
0322 };
0323 
0324 class DDMultiUnion : public DDMultiUnionSolid {
0325 public:
0326   DDMultiUnion(const DDSolid& s);
0327   DDMultiUnion(void) = delete;
0328 };
0329 
0330 class DDIntersection : public DDBooleanSolid {
0331 public:
0332   DDIntersection(const DDSolid& s);
0333   DDIntersection(void) = delete;
0334 };
0335 
0336 class DDSubtraction : public DDBooleanSolid {
0337 public:
0338   DDSubtraction(const DDSolid& s);
0339   DDSubtraction(void) = delete;
0340 };
0341 
0342 class DDSphere : public DDSolid {
0343 public:
0344   DDSphere(const DDSolid& s);
0345   DDSphere(void) = delete;
0346 
0347   double innerRadius(void) const;
0348   double outerRadius(void) const;
0349   double startPhi(void) const;
0350   double deltaPhi(void) const;
0351   double startTheta(void) const;
0352   double deltaTheta(void) const;
0353 };
0354 
0355 class DDOrb : public DDSolid {
0356 public:
0357   DDOrb(const DDSolid& s);
0358   DDOrb(void) = delete;
0359 
0360   double radius(void) const;
0361 };
0362 
0363 class DDEllipticalTube : public DDSolid {
0364 public:
0365   DDEllipticalTube(const DDSolid& s);
0366   DDEllipticalTube(void) = delete;
0367 
0368   double xSemiAxis(void) const;
0369   double ySemiAxis(void) const;
0370   double zHeight(void) const;
0371 };
0372 
0373 class DDEllipsoid : public DDSolid {
0374 public:
0375   DDEllipsoid(const DDSolid& s);
0376   DDEllipsoid(void) = delete;
0377 
0378   double xSemiAxis(void) const;
0379   double ySemiAxis(void) const;
0380   double zSemiAxis(void) const;
0381   double zBottomCut(void) const;
0382   double zTopCut(void) const;
0383 };
0384 
0385 class DDParallelepiped : public DDSolid {
0386 public:
0387   DDParallelepiped(const DDSolid& s);
0388   DDParallelepiped(void) = delete;
0389 
0390   double xHalf(void) const;
0391   double yHalf(void) const;
0392   double zHalf(void) const;
0393   double alpha(void) const;
0394   double theta(void) const;
0395   double phi(void) const;
0396 };
0397 
0398 // Solid generation functions
0399 //
0400 struct DDSolidFactory {
0401   //! Creates an assembly
0402   static DDSolid assembly(const DDName& name);
0403 
0404   //! Creates a box with side length 2*xHalf, 2*yHalf, 2*zHalf
0405   /** \arg \c name unique name identifying the box
0406       \arg \c xHalf half length in x 
0407       \arg \c yHalf half length in y
0408       \arg \c zHalf helf length in z
0409       The center of the box (for positioning) is the center of gravity.
0410   */
0411   static DDSolid box(const DDName& name, double xHalf, double yHalf, double zHalf);
0412 
0413   //! Creates a polycone (refere to \b Geant3 or \b Geant4 documentation)
0414   /** The center of the polycone (for positioning) is the center of coordinates
0415       of the polycone definition (x=y=z=0)
0416   */
0417   static DDSolid polycone(const DDName& name,
0418                           double startPhi,
0419                           double deltaPhi,
0420                           const std::vector<double>& z,
0421                           const std::vector<double>& rmin,
0422                           const std::vector<double>& rmax);
0423 
0424   //! Creates a polycone (refere to \b Geant4 documentation)
0425   /** The center of the polycone (for positioning) is the center of coordinates
0426       of the polycone definition (x=y=z=0)
0427   */
0428   static DDSolid polycone(
0429       const DDName& name, double startPhi, double deltaPhi, const std::vector<double>& z, const std::vector<double>& r);
0430 
0431   //! Creates a polyhedra (refere to \b Geant3 or \b Geant4 documentation)
0432   /** The center of the polyhedra (for positioning) is the center of coordinates
0433       of the polyhedra definition (x=y=z=0)
0434   */
0435   static DDSolid polyhedra(const DDName& name,
0436                            int sides,
0437                            double startPhi,
0438                            double deltaPhi,
0439                            const std::vector<double>& z,
0440                            const std::vector<double>& rmin,
0441                            const std::vector<double>& rmax);
0442 
0443   //! Creates a polyhedra (refere to \b Geant4 documentation)
0444   /** The center of the polyhedra (for positioning) is the center of coordinates
0445       of the polyhedra definition (x=y=z=0)
0446   */
0447   static DDSolid polyhedra(const DDName& name,
0448                            int sides,
0449                            double startPhi,
0450                            double deltaPhi,
0451                            const std::vector<double>& z,
0452                            const std::vector<double>& r);
0453 
0454   static DDSolid unionSolid(
0455       const DDName& name, const DDSolid& a, const DDSolid& b, const DDTranslation& t, const DDRotation& r);
0456 
0457   static DDSolid multiUnionSolid(const DDName& name,
0458                                  const std::vector<DDSolid>& a,
0459                                  const std::vector<DDTranslation>& t,
0460                                  const std::vector<DDRotation>& r);
0461 
0462   static DDSolid intersection(
0463       const DDName& name, const DDSolid& a, const DDSolid& b, const DDTranslation& t, const DDRotation& r);
0464 
0465   static DDSolid subtraction(
0466       const DDName& name, const DDSolid& a, const DDSolid& b, const DDTranslation& t, const DDRotation& r);
0467 
0468   static DDSolid trap(const DDName& name,
0469                       double pDz,
0470                       double pTheta,
0471                       double pPhi,
0472                       double pDy1,
0473                       double pDx1,
0474                       double pDx2,
0475                       double pAlp1,
0476                       double pDy2,
0477                       double pDx3,
0478                       double pDx4,
0479                       double pAlp2);
0480 
0481   static DDSolid pseudoTrap(const DDName& name,
0482                             double pDx1,    /**< Half-length along x at the surface positioned at -dz */
0483                             double pDx2,    /**< Half-length along x at the surface positioned at +dz */
0484                             double pDy1,    /**< Half-length along y at the surface positioned at -dz */
0485                             double pDy2,    /**< Half-length along y at the surface positioned at +dz */
0486                             double pDz,     /**< Half of the height of the pseudo trapezoid along z */
0487                             double radius,  /**< radius of the cut-out (negative sign) or rounding (pos. sign) */
0488                             bool atMinusZ); /**< if true, the cut-out or rounding is applied at -dz, else at +dz */
0489 
0490   static DDSolid truncTubs(const DDName& name,
0491                            double zHalf,      /**< half-length of the z-axis */
0492                            double rIn,        /**< inner radius of the tube-section */
0493                            double rOut,       /**< outer radius of the tube-section */
0494                            double startPhi,   /**< starting angle of the tube-section */
0495                            double deltaPhi,   /**< spanning angle of the tube-section */
0496                            double cutAtStart, /**< tructation */
0497                            double cutAtDelta, /**< */
0498                            bool cutInside);
0499 
0500   static DDSolid tubs(const DDName& name, double zhalf, double rIn, double rOut, double startPhi, double deltaPhi);
0501 
0502   static DDSolid cuttubs(const DDName& name,
0503                          double zhalf,
0504                          double rIn,
0505                          double rOut,
0506                          double startPhi,
0507                          double deltaPhi,
0508                          double lx,
0509                          double ly,
0510                          double lz,
0511                          double tx,
0512                          double ty,
0513                          double tz);
0514 
0515   static DDSolid cons(const DDName& name,
0516                       double zhalf,
0517                       double rInMinusZ,
0518                       double rOutMinusZ,
0519                       double rInPlusZ,
0520                       double rOutPlusZ,
0521                       double phiFrom,
0522                       double deltaPhi);
0523 
0524   static DDSolid torus(const DDName& name, double rMin, double rMax, double rTorus, double startPhi, double deltaPhi);
0525 
0526   static DDSolid sphere(const DDName& name,
0527                         double innerRadius,
0528                         double outerRadius,
0529                         double startPhi,
0530                         double deltaPhi,
0531                         double startTheta,
0532                         double deltaTheta);
0533 
0534   static DDSolid orb(const DDName& name, double radius);
0535 
0536   static DDSolid ellipticalTube(const DDName& name, double xSemiAxis, double ySemiAxis, double zHeight);
0537 
0538   static DDSolid ellipsoid(const DDName& name,
0539                            double xSemiAxis,
0540                            double ySemiAxis,
0541                            double zSemiAxis,
0542                            double zBottomCut = 0.,
0543                            double zTopCut = 0.);
0544 
0545   static DDSolid parallelepiped(
0546       const DDName& name, double xHalf, double yHalf, double zHalf, double alpha, double theta, double phi);
0547 
0548   static DDSolid extrudedpolygon(const DDName& name,
0549                                  const std::vector<double>& x,
0550                                  const std::vector<double>& y,
0551                                  const std::vector<double>& z,
0552                                  const std::vector<double>& zx,
0553                                  const std::vector<double>& zy,
0554                                  const std::vector<double>& zscale);
0555 
0556   static DDSolid shapeless(const DDName& name);
0557 
0558   static DDSolid reflection(const DDName& name, const DDSolid& s);
0559 };
0560 
0561 #endif