Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 10:12:36

0001 //==========================================================================
0002 //  AIDA Detector description implementation 
0003 //--------------------------------------------------------------------------
0004 // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
0005 // All rights reserved.
0006 //
0007 // For the licensing terms see $DD4hepINSTALL/LICENSE.
0008 // For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
0009 //
0010 // Author     : M.Frank
0011 //
0012 //==========================================================================
0013 
0014 #ifndef DD4HEP_SHAPES_H
0015 #define DD4HEP_SHAPES_H
0016 
0017 // Framework include files
0018 #include <DD4hep/Handle.h>
0019 #include <DD4hep/Objects.h>
0020 #include <DD4hep/DD4hepUnits.h>
0021 
0022 // C/C++ include files
0023 #include <vector>
0024 #include <string>
0025 
0026 #ifdef __GNUC__
0027 #pragma GCC diagnostic push
0028 #pragma GCC diagnostic ignored "-Wdeprecated" // Code that causes warning goes here
0029 #endif
0030 
0031 // ROOT include files
0032 #include <TGeoCone.h>
0033 #include <TGeoPgon.h>
0034 #include <TGeoPcon.h>
0035 #include <TGeoArb8.h>
0036 #include <TGeoTrd1.h>
0037 #include <TGeoTrd2.h>
0038 #include <TGeoTube.h>
0039 #include <TGeoEltu.h>
0040 #include <TGeoXtru.h>
0041 #include <TGeoHype.h>
0042 #include <TGeoTorus.h>
0043 #include <TGeoSphere.h>
0044 #include <TGeoHalfSpace.h>
0045 #include <TGeoParaboloid.h>
0046 #include <TGeoScaledShape.h>
0047 #include <TGeoCompositeShape.h>
0048 #include <TGeoShapeAssembly.h>
0049 #include <TGeoPara.h>
0050 #include <TGeoTessellated.h>
0051 
0052 #ifdef __GNUC__
0053 #pragma GCC diagnostic pop
0054 #endif
0055 
0056 /// Namespace for the AIDA detector description toolkit
0057 namespace dd4hep {
0058 
0059   class Volume;
0060 
0061   /** Utitlity functions   */
0062   /// Pretty print of solid attributes
0063   std::string toStringSolid(const TGeoShape* shape, int precision=2);
0064 
0065   /// Output mesh vertices to string
0066   std::string toStringMesh(const TGeoShape* shape, int precision=2);
0067   
0068   /// Retrieve tag name from shape type
0069   std::string get_shape_tag(const TGeoShape* shape);
0070   
0071   /// Access Shape dimension parameters (As in TGeo, but angles in radians rather than degrees)
0072   std::vector<double> get_shape_dimensions(TGeoShape* shape);
0073   
0074   /// Set the shape dimensions (As for the TGeo shape, but angles in rad rather than degrees)
0075   void set_shape_dimensions(TGeoShape* shape, const std::vector<double>& params);
0076 
0077   /// Type check of various shapes. Result like dynamic_cast. Compare with python's isinstance(obj,type)
0078   template <typename SOLID> bool isInstance(const Handle<TGeoShape>& solid);
0079   /// Type check of various shapes. Do not allow for polymorphism. Types must match exactly
0080   template <typename SOLID> bool isA(const Handle<TGeoShape>& solid);
0081   /// Access Shape dimension parameters (As in TGeo, but angles in radians rather than degrees)
0082   template <typename SOLID> std::vector<double> dimensions(const Handle<TGeoShape>& solid);
0083   /// Set the shape dimensions. As for the TGeo shape, but angles in rad rather than degrees.
0084   template <typename SOLID> void set_dimensions(SOLID solid, const std::vector<double>& params);
0085 
0086   namespace detail   {
0087     inline std::vector<double> _make_vector(const double* values, size_t length)   {
0088       return {values, values+length};
0089     }
0090     template <typename SOLID> std::vector<double> _extract_vector(const SOLID* solid,
0091                                                                   double (SOLID::*extract)(Int_t) const,
0092                                                                   Int_t (SOLID::*len)() const)   {
0093       std::vector<double> result;
0094       Int_t count = (solid->*len)();
0095       for(Int_t i=0; i<count; ++i) result.emplace_back((solid->*extract)(i));
0096       return result;
0097     }
0098     template <typename SOLID> std::vector<double> zPlaneZ(const SOLID* solid)   {
0099       const auto* shape = solid->access();
0100       return _make_vector(shape->GetZ(), shape->GetNz());
0101     }
0102     template <typename SOLID> std::vector<double> zPlaneRmin(const SOLID* solid)   {
0103       const auto* shape = solid->access();
0104       return _make_vector(shape->GetRmin(), shape->GetNz());
0105     }
0106     template <typename SOLID> std::vector<double> zPlaneRmax(const SOLID* solid)   {
0107       const auto* shape = solid->access();
0108       return _make_vector(shape->GetRmax(), shape->GetNz());
0109     }
0110 
0111   }
0112   
0113   ///  Base class for Solid (shape) objects
0114   /**
0115    *   Generic handle holding an object of base TGeoShape.
0116    *
0117    *   One note about divisions:
0118    *   =========================
0119    *   Since dd4hep requires Volumes (aka TGeoVolume) and PlacedVolumes (aka TGeoNode)
0120    *   to be enhaced with the user extension mechanism shape divisions MUST be
0121    *   done using the division mechanism of the dd4hep shape or volume wrapper.
0122    *   Otherwise the enhancements are not added and you shall get exception
0123    *   when dd4hep is closing the geometry.
0124    *   The same argument holds when a division is made from a Volume.
0125    *   Unfortunately there is no reasonable way to intercept this call to the
0126    *   TGeo objects - except to sub-class each of them, which is not really 
0127    *   acceptable either.
0128    *
0129    *   For any further documentation please see the following ROOT documentation:
0130    *   \see http://root.cern.ch/root/html/TGeoShape.html
0131    *
0132    *   \author  M.Frank
0133    *   \version 1.0
0134    *   \ingroup DD4HEP_CORE
0135    */
0136   template <typename T> class Solid_type: public Handle<T> {
0137   public:
0138     template <typename Q> friend void set_dimensions(Q ptr, const std::vector<double>& params);
0139     
0140   protected:
0141     void _setDimensions(double* param)   const;
0142     /// Assign pointrs and register solid to geometry
0143     void _assign(T* n, const std::string& nam, const std::string& tit, bool cbbox);
0144 
0145   public:
0146 
0147     /// Default constructor for uninitialized object
0148     Solid_type() = default;
0149     /// Move constructor
0150     Solid_type(Solid_type&& e) = default;
0151     /// Copy constructor
0152     Solid_type(const Solid_type& e) = default;
0153     /// Direct assignment using the implementation pointer
0154     Solid_type(T* p) : Handle<T>(p) {  }
0155     /// Move Constructor from handle
0156     Solid_type(Handle<T>&& e) : Handle<T>(std::move(e)) {  }
0157     /// Copy Constructor from handle
0158     Solid_type(const Handle<T>& e) : Handle<T>(e) {  }
0159     /// Constructor to be used when passing an already created object: need to check pointers
0160     template <typename Q> Solid_type(const Handle<Q>& e) : Handle<T>(e) {  }
0161     /// Assignment move operator
0162     Solid_type& operator=(Solid_type&& copy) = default;
0163     /// Assignment copy operator
0164     Solid_type& operator=(const Solid_type& copy) = default;
0165 
0166     /// Access to shape name
0167     const char* name() const;
0168     /// Set new shape name
0169     Solid_type<T>& setName(const char* value);
0170     /// Set new shape name
0171     Solid_type<T>& setName(const std::string& value);
0172 
0173     /// Access to shape title (GetTitle accessor of the TGeoShape)
0174     const char* title() const;
0175 
0176     /// Access to shape type (The TClass name of the ROOT implementation)
0177     const char* type() const;
0178     /// Auto conversion to underlying ROOT object
0179     operator T*() const {
0180       return this->m_element;
0181     }
0182     /// Overloaded operator -> to access underlying object
0183     T* operator->() const {
0184       return this->m_element;
0185     }
0186     /// Access the dimensions of the shape: inverse of the setDimensions member function
0187     std::vector<double> dimensions();
0188     /// Set the shape dimensions. As for the TGeo shape, but angles in rad rather than degrees.
0189     Solid_type& setDimensions(const std::vector<double>& params);
0190     /// Conversion to string for pretty print
0191     std::string toString(int precision=2) const   {
0192       return toStringSolid(this->m_element,precision);
0193     }
0194     /// Divide volume into subsections (See the ROOT manuloa for details)
0195     TGeoVolume* divide(const Volume& voldiv, const std::string& divname,
0196                        int iaxis, int ndiv, double start, double step)  const;
0197   };
0198   typedef Solid_type<TGeoShape> Solid;
0199 
0200   /// Class describing a shape-less solid shape
0201   /**
0202    *   For any further documentation please see the following ROOT documentation:
0203    *   \see http://root.cern.ch/root/html/TGeoShapeAssembly.html
0204    *
0205    *
0206    *   \author  M.Frank
0207    *   \version 1.0
0208    *   \ingroup DD4HEP_CORE
0209    */
0210   class ShapelessSolid: public Solid_type<TGeoShapeAssembly> {
0211   public:
0212     /// Default constructor
0213     ShapelessSolid() = default;
0214     /// Move constructor from handle
0215     ShapelessSolid(ShapelessSolid&& e) = default;
0216     /// Copy constructor from handle
0217     ShapelessSolid(const ShapelessSolid& e) = default;
0218     /// Constructor to be used with an existing object
0219     template <typename Q> ShapelessSolid(const Q* p) : Solid_type<TGeoShapeAssembly>(p) { }
0220     /// Constructor to be used with an existing object
0221     template <typename Q> ShapelessSolid(const Handle<Q>& e) : Solid_type<TGeoShapeAssembly>(e) { }
0222     /// Constructor to create an anonymous new shapeless solid
0223     ShapelessSolid(const std::string& name);
0224     /// Move Assignment operator
0225     ShapelessSolid& operator=(ShapelessSolid&& copy) = default;
0226     /// Copy Assignment operator
0227     ShapelessSolid& operator=(const ShapelessSolid& copy) = default;
0228   };
0229 
0230   /// Class describing a Scale shape
0231   /**
0232    *   For any further documentation please see the following ROOT documentation:
0233    *   \see http://root.cern.ch/root/html/TGeoScaledShape.html
0234    *
0235    *
0236    *   \author  M.Frank
0237    *   \version 1.0
0238    *   \ingroup DD4HEP_CORE
0239    */
0240   class Scale : public Solid_type<TGeoScaledShape> {
0241   protected:
0242     /// Internal helper method to support object construction
0243     void make(const std::string& name, Solid base_solid, double x_scale, double y_scale, double z_scale);
0244 
0245   public:
0246     /// Default constructor
0247     Scale() = default;
0248     /// Move constructor
0249     Scale(Scale&& e) = default;
0250     /// Copy constructor
0251     Scale(const Scale& e) = default;
0252     /// Constructor to be used with an existing object
0253     template <typename Q> Scale(const Q* p) : Solid_type<TGeoScaledShape>(p) { }
0254     /// Copy Constructor to be used with an existing object handle
0255     template <typename Q> Scale(const Handle<Q>& e) : Solid_type<TGeoScaledShape>(e) { }
0256 
0257     /// Constructor to create an anonymous new Scale object (retrieves name from volume)
0258     Scale(Solid base_solid, double x_scale, double y_scale, double z_scale)
0259     { make("", base_solid, x_scale, y_scale, z_scale);    }
0260     /// Constructor to create a named new Scale object (retrieves name from volume)
0261     Scale(const std::string& nam, Solid base_solid, double x_scale, double y_scale, double z_scale)
0262     { make(nam.c_str(), base_solid, x_scale, y_scale, z_scale);    }
0263 
0264     /// Constructor to create an anonymous new Scale object (retrieves name from volume)
0265     template <typename X, typename Y, typename Z>
0266     Scale(Solid base_solid, const X& x_scale, const Y& y_scale, const Z& z_scale)
0267     { make("", base_solid, _toDouble(x_scale), _toDouble(y_scale), _toDouble(z_scale));    }
0268     /// Constructor to create a named new Scale object (retrieves name from volume)
0269     template <typename X, typename Y, typename Z>
0270     Scale(const std::string& nam, Solid base_solid, const X& x_scale, const Y& y_scale, const Z& z_scale)
0271     { make(nam.c_str(), base_solid, _toDouble(x_scale), _toDouble(y_scale), _toDouble(z_scale));  }
0272 
0273     /// Move Assignment operator
0274     Scale& operator=(Scale&& copy) = default;
0275     /// Copy Assignment operator
0276     Scale& operator=(const Scale& copy) = default;
0277     /// Access x-scale factor
0278     double scale_x() const;
0279     /// Access y-scale factor
0280     double scale_y() const;
0281     /// Access z-scale factor
0282     double scale_z() const;
0283   };
0284 
0285   /// Class describing a box shape
0286   /**
0287    *   For any further documentation please see the following ROOT documentation:
0288    *   \see http://root.cern.ch/root/html/TGeoBBox.html
0289    *
0290    *
0291    *   \author  M.Frank
0292    *   \version 1.0
0293    *   \ingroup DD4HEP_CORE
0294    */
0295   class Box : public Solid_type<TGeoBBox> {
0296   protected:
0297     /// Internal helper method to support object construction
0298     void make(const std::string& name, double x_val, double y_val, double z_val);
0299 
0300   public:
0301     /// Default constructor
0302     Box() = default;
0303     /// Move constructor
0304     Box(Box&& e) = default;
0305     /// Copy constructor
0306     Box(const Box& e) = default;
0307     /// Constructor to be used with an existing object
0308     template <typename Q> Box(const Q* p) : Solid_type<TGeoBBox>(p) { }
0309     /// Copy Constructor to be used with an existing object handle
0310     template <typename Q> Box(const Handle<Q>& e) : Solid_type<TGeoBBox>(e) { }
0311 
0312     /// Constructor to create an anonymous new box object (retrieves name from volume)
0313     Box(double x_val, double y_val, double z_val)
0314     { make("", x_val, y_val, z_val);    }
0315     /// Constructor to create a named new box object (retrieves name from volume)
0316     Box(const std::string& nam, double x_val, double y_val, double z_val)
0317     { make(nam.c_str(), x_val, y_val, z_val);    }
0318 
0319     /// Constructor to create an anonymous new box object (retrieves name from volume)
0320     template <typename X, typename Y, typename Z>
0321     Box(const X& x_val, const Y& y_val, const Z& z_val)
0322     { make("", _toDouble(x_val), _toDouble(y_val), _toDouble(z_val));    }
0323     /// Constructor to create a named new box object (retrieves name from volume)
0324     template <typename X, typename Y, typename Z>
0325     Box(const std::string& nam, const X& x_val, const Y& y_val, const Z& z_val)
0326     { make(nam.c_str(), _toDouble(x_val), _toDouble(y_val), _toDouble(z_val));  }
0327 
0328     /// Move Assignment operator
0329     Box& operator=(Box&& copy) = default;
0330     /// Copy Assignment operator
0331     Box& operator=(const Box& copy) = default;
0332     /// Set the box dimensions
0333     Box& setDimensions(double x_val, double y_val, double z_val);
0334     /// Access half "length" of the box
0335     double x() const;
0336     /// Access half "width" of the box
0337     double y() const;
0338     /// Access half "depth" of the box
0339     double z() const;
0340   };
0341 
0342   /// Class describing half-space
0343   /**
0344    *   For any further documentation please see the following ROOT documentation:
0345    *   \see http://root.cern.ch/root/html/TGeoHalfSpace.html
0346    *
0347    *
0348    *   \author  M.Frank
0349    *   \version 1.0
0350    *   \ingroup DD4HEP_CORE
0351    */
0352   class HalfSpace : public Solid_type<TGeoHalfSpace> {
0353   protected:
0354     /// Internal helper method to support object construction
0355     void make(const std::string& name, const double* const point, const double* const normal);
0356 
0357   public:
0358     /// Default constructor
0359     HalfSpace() = default;
0360     /// Move Constructor
0361     HalfSpace(HalfSpace&& e) = default;
0362     /// Copy Constructor
0363     HalfSpace(const HalfSpace& e) = default;
0364     /// Constructor to be used with an existing object
0365     template <typename Q> HalfSpace(const Q* p) : Solid_type<Object>(p) { }
0366     /// Constructor to be used with an existing object
0367     template <typename Q> HalfSpace(const Handle<Q>& e) : Solid_type<Object>(e) { }
0368 
0369     /// Constructor to create an new halfspace object from a point on a plane and the plane normal
0370     HalfSpace(const double* const point, const double* const normal)
0371     { make("", point, normal);              }
0372 
0373     /// Constructor to create an new named halfspace object from a point on a plane and the plane normal
0374     HalfSpace(const std::string& nam, const double* const point, const double* const normal)
0375     { make(nam.c_str(), point, normal);    }
0376 
0377     /// Move Assignment operator
0378     HalfSpace& operator=(HalfSpace&& copy) = default;
0379     /// Copy Assignment operator
0380     HalfSpace& operator=(const HalfSpace& copy) = default;
0381 
0382     /// Accessor: positioning point
0383     Position position()  const   {
0384       const double* pos = access()->GetPoint();
0385       return {pos[0], pos[1], pos[2]};
0386     }
0387     /// Accessor: normal vector spanning plane at positioning point
0388     Direction normal()  const   {
0389       const double* n = access()->GetNorm();
0390       return {n[0], n[1], n[2]};
0391     }
0392   };
0393 
0394   /// Class describing a cone shape
0395   /**
0396    *   For any further documentation please see the following ROOT documentation:
0397    *   \see http://root.cern.ch/root/html/TGeoCone.html
0398    *
0399    *   \author  M.Frank
0400    *   \version 1.0
0401    *   \ingroup DD4HEP_CORE
0402    */
0403   class Cone : public Solid_type<TGeoCone> {
0404   protected:
0405     /// Internal helper method to support object construction
0406     void make(const std::string& name, double z, double rmin1, double rmax1, double rmin2, double rmax2);
0407   public:
0408     /// Default constructor
0409     Cone() = default;
0410     /// Move Constructor
0411     Cone(Cone&& e) = default;
0412     /// Copy Constructor
0413     Cone(const Cone& e) = default;
0414     /// Constructor to be used with an existing object
0415     template <typename Q> Cone(const Q* p) : Solid_type<Object>(p) { }
0416     /// Constructor to be used when passing an already created object
0417     template <typename Q> Cone(const Handle<Q>& e) : Solid_type<Object>(e) { }
0418 
0419     /// Constructor to create a new anonymous object with attribute initialization
0420     Cone(double z, double rmin1, double rmax1, double rmin2, double rmax2)
0421     {     this->make("", z, rmin1, rmax1, rmin2, rmax2);                                 }
0422     /// Constructor to create a new anonymous object with attribute initialization
0423     template <typename Z, typename RMIN1, typename RMAX1, typename RMIN2, typename RMAX2>
0424     Cone(const Z& z, const RMIN1& rmin1, const RMAX1& rmax1, const RMIN2& rmin2, const RMAX2& rmax2)
0425     {     this->make("", _toDouble(z), _toDouble(rmin1), _toDouble(rmax1), _toDouble(rmin2), _toDouble(rmax2)); }
0426 
0427     /// Constructor to create a new anonymous object with attribute initialization
0428     Cone(const std::string& nam, double z, double rmin1, double rmax1, double rmin2, double rmax2)
0429     {     this->make(nam, z, rmin1, rmax1, rmin2, rmax2);                                 }
0430     /// Constructor to create a new anonymous object with attribute initialization
0431     template <typename Z, typename RMIN1, typename RMAX1, typename RMIN2, typename RMAX2>
0432     Cone(const std::string& nam, const Z& z, const RMIN1& rmin1, const RMAX1& rmax1, const RMIN2& rmin2, const RMAX2& rmax2)
0433     {     this->make(nam, _toDouble(z), _toDouble(rmin1), _toDouble(rmax1), _toDouble(rmin2), _toDouble(rmax2)); }
0434 
0435     /// Move Assignment operator
0436     Cone& operator=(Cone&& copy) = default;
0437     /// Copy Assignment operator
0438     Cone& operator=(const Cone& copy) = default;
0439     /// Set the box dimensions
0440     Cone& setDimensions(double z, double rmin1, double rmax1, double rmin2, double rmax2);
0441 
0442     /// Accessor: delta-z value
0443     double dZ() const                      { return access()->GetDz();               }
0444     /// Accessor: r-min-1 value
0445     double rMin1() const                   { return access()->GetRmin1();            }
0446     /// Accessor: r-min-2 value
0447     double rMin2() const                   { return access()->GetRmin2();            }
0448     /// Accessor: r-max-1 value
0449     double rMax1() const                   { return access()->GetRmax1();            }
0450     /// Accessor: r-max-2 value
0451     double rMax2() const                   { return access()->GetRmax2();            }
0452   };
0453 
0454   /// Class describing a Polycone shape
0455   /**
0456    *   Polycone. It has at least 9 parameters :
0457    *      - the lower phi limit;
0458    *      - the range in phi;
0459    *      - the number of z planes (at least two) where the inner/outer
0460    *        radii are changing;
0461    *      - z coordinate, inner and outer radius for each z plane
0462    *
0463    *
0464    *   For any further documentation please see the following ROOT documentation:
0465    *   \see http://root.cern.ch/root/html/TGeoPcon.html
0466    *
0467    *
0468    *   \author  M.Frank
0469    *   \version 1.0
0470    *   \ingroup DD4HEP_CORE
0471    */
0472   class Polycone : public Solid_type<TGeoPcon> {
0473   public:
0474     /// Default constructor
0475     Polycone() = default;
0476     /// Move constructor
0477     Polycone(Polycone&& e) = default;
0478     /// Copy constructor
0479     Polycone(const Polycone& e) = default;
0480     /// Constructor to be used with an existing object
0481     template <typename Q> Polycone(const Q* p) : Solid_type<Object>(p) {  }
0482     /// Constructor to be used when reading the already parsed polycone object
0483     template <typename Q> Polycone(const Handle<Q>& e) : Solid_type<Object>(e) { }
0484 
0485     /// Constructor to create a new polycone object
0486     Polycone(double startPhi, double deltaPhi);
0487     /// Constructor to create a new polycone object. Add at the same time all Z planes
0488     Polycone(double startPhi, double deltaPhi,
0489              const std::vector<double>& r, const std::vector<double>& z);
0490     /// Constructor to create a new polycone object. Add at the same time all Z planes
0491     Polycone(double startPhi, double deltaPhi,
0492              const std::vector<double>& rmin, const std::vector<double>& rmax, const std::vector<double>& z);
0493     
0494     /// Constructor to create a new named polycone object
0495     Polycone(const std::string& name, double startPhi, double deltaPhi);
0496     /// Constructor to create a new named polycone object. Add at the same time all Z planes
0497     Polycone(const std::string& name, double startPhi, double deltaPhi,
0498              const std::vector<double>& r, const std::vector<double>& z);
0499     /// Constructor to create a new named polycone object. Add at the same time all Z planes
0500     Polycone(const std::string& name, double startPhi, double deltaPhi,
0501              const std::vector<double>& rmin, const std::vector<double>& rmax, const std::vector<double>& z);
0502 
0503     /// Move Assignment operator
0504     Polycone& operator=(Polycone&& copy) = default;
0505     /// Copy Assignment operator
0506     Polycone& operator=(const Polycone& copy) = default;
0507 
0508     /// Add Z-planes to the Polycone
0509     void addZPlanes(const std::vector<double>& rmin, const std::vector<double>& rmax, const std::vector<double>& z);
0510 
0511     /// Accessor: start-phi value
0512     double startPhi() const                { return access()->GetPhi1()*dd4hep::deg; }
0513     /// Accessor: delta-phi value
0514     double deltaPhi() const                { return access()->GetDphi()*dd4hep::deg; }
0515 
0516     /// Accessor: z value
0517     double z(int which) const              { return access()->GetZ(which);           }
0518     /// Accessor: r-min value  
0519     double rMin(int which) const           { return access()->GetRmin(which);        }
0520     /// Accessor: r-max value
0521     double rMax(int which) const           { return access()->GetRmax(which);        }
0522 
0523     /// Accessor: vector of z-values for Z-planes value
0524     std::vector<double> zPlaneZ() const    { return detail::zPlaneZ(this);           }
0525     /// Accessor: vector of rMin-values for Z-planes value
0526     std::vector<double> zPlaneRmin() const { return detail::zPlaneRmin(this);        }
0527     /// Accessor: vector of rMax-values for Z-planes value
0528     std::vector<double> zPlaneRmax() const { return detail::zPlaneRmax(this);        }
0529   };
0530 
0531   /// Class describing a cone segment shape
0532   /**
0533    *   A ConeSegment is, in the general case, a Phi segment of a cone, with
0534    *   half-length dz, inner and outer radii specified at -dz and +dz.
0535    *
0536    *   For any further documentation please see the following ROOT documentation:
0537    *   \see http://root.cern.ch/root/html/TGeoConeSeg.html
0538    *
0539    *   \author  M.Frank
0540    *   \version 1.0
0541    *   \ingroup DD4HEP_CORE
0542    */
0543   class ConeSegment : public Solid_type<TGeoConeSeg> {
0544     void make(const std::string& name,
0545               double dz, 
0546               double rmin1,     double rmax1,
0547               double rmin2,     double rmax2,
0548               double startPhi,  double endPhi);
0549   public:
0550     /// Default constructor
0551     ConeSegment() = default;
0552     /// Move Constructor
0553     ConeSegment(ConeSegment&& e) = default;
0554     /// Copy Constructor
0555     ConeSegment(const ConeSegment& e) = default;
0556     /// Constructor to be used with an existing object
0557     template <typename Q> ConeSegment(const Q* p) : Solid_type<Object>(p) {  }
0558     /// Constructor to be used when reading the already parsed ConeSegment object
0559     template <typename Q> ConeSegment(const Handle<Q>& e) : Solid_type<Object>(e) {  }
0560 
0561     /// Constructor to create a new ConeSegment object
0562     ConeSegment(double dz, double rmin1, double rmax1,
0563                 double rmin2, double rmax2, double startPhi = 0.0, double endPhi = 2.0 * M_PI)
0564     {  make("", dz, rmin1, rmax1, rmin2, rmax2, startPhi, endPhi);   }
0565     /// Constructor to create a new ConeSegment object
0566     template <typename DZ,
0567               typename RMIN1, typename RMAX1,
0568               typename RMIN2, typename RMAX2,
0569               typename STARTPHI, typename ENDPHI>
0570     ConeSegment(DZ dz, RMIN1 rmin1, RMAX1 rmax1, RMIN2 rmin2, RMAX2 rmax2,
0571                 STARTPHI startPhi = 0.0, ENDPHI endPhi = 2.0 * M_PI)
0572     {  make("", _toDouble(dz),
0573             _toDouble(rmin1), _toDouble(rmax1),
0574             _toDouble(rmin2), _toDouble(rmax2),
0575             _toDouble(startPhi), _toDouble(endPhi));   }
0576     /// Constructor to create a new named ConeSegment object
0577     ConeSegment(const std::string& nam, double dz, double rmin1, double rmax1,
0578                 double rmin2, double rmax2, double startPhi = 0.0, double endPhi = 2.0 * M_PI)
0579     {  make(nam, dz, rmin1, rmax1, rmin2, rmax2, startPhi, endPhi);  }
0580     /// Constructor to create a new named ConeSegment object
0581     template <typename DZ,
0582               typename RMIN1, typename RMAX1,
0583               typename RMIN2, typename RMAX2,
0584               typename STARTPHI, typename ENDPHI>
0585     ConeSegment(const std::string& nam, DZ dz, RMIN1 rmin1, RMAX1 rmax1, RMIN2 rmin2, RMAX2 rmax2,
0586                 STARTPHI startPhi = 0.0, ENDPHI endPhi = 2.0 * M_PI)
0587     {  make(nam, _toDouble(dz),
0588             _toDouble(rmin1), _toDouble(rmax1),
0589             _toDouble(rmin2), _toDouble(rmax2),
0590             _toDouble(startPhi), _toDouble(endPhi));   }
0591 
0592     /// Move Assignment operator
0593     ConeSegment& operator=(ConeSegment&& copy) = default;
0594     /// Copy Assignment operator
0595     ConeSegment& operator=(const ConeSegment& copy) = default;
0596     /// Set the cone segment dimensions
0597     ConeSegment& setDimensions(double dz, double rmin1, double rmax1,
0598                                double rmin2, double rmax2,
0599                                double startPhi = 0.0, double endPhi = 2.0 * M_PI);
0600 
0601     /// Accessor: start-phi value
0602     double startPhi() const                { return access()->GetPhi1()*dd4hep::deg; }
0603     /// Accessor: end-phi value
0604     double endPhi() const                  { return access()->GetPhi2()*dd4hep::deg; }
0605     /// Accessor: delta-z value
0606     double dZ() const                      { return access()->GetDz();               }
0607     /// Accessor: r-min-1 value
0608     double rMin1() const                   { return access()->GetRmin1();            }
0609     /// Accessor: r-min-2 value
0610     double rMin2() const                   { return access()->GetRmin2();            }
0611     /// Accessor: r-max-1 value
0612     double rMax1() const                   { return access()->GetRmax1();            }
0613     /// Accessor: r-max-2 value
0614     double rMax2() const                   { return access()->GetRmax2();            }
0615   };
0616 
0617   /// Class describing a tube shape of a section of a tube
0618   /**
0619    *   TGeoTube - cylindrical tube class. It takes 3 parameters :
0620    *            inner radius, outer radius and half-length dz.
0621    *
0622    *   For any further documentation please see the following ROOT documentation:
0623    *   \see http://root.cern.ch/root/html/TGeoConeSeg.html
0624    *
0625    *   \author  M.Frank
0626    *   \version 1.0
0627    *   \ingroup DD4HEP_CORE
0628    */
0629   class Tube : public Solid_type<TGeoTubeSeg> {
0630   protected:
0631     /// Internal helper method to support object construction
0632     void make(const std::string& nam, double rmin, double rmax, double z, double startPhi, double endPhi);
0633 
0634   public:
0635     /// Default constructor
0636     Tube() = default;
0637     /// Move Constructor
0638     Tube(Tube&& e) = default;
0639     /// Copy Constructor
0640     Tube(const Tube& e) = default;
0641     /// Constructor to be used with an existing object
0642     template <typename Q> Tube(const Q* p) : Solid_type<Object>(p) {  }
0643     /// Constructor to assign an object
0644     template <typename Q> Tube(const Handle<Q>& e) : Solid_type<Object>(e) {  }
0645 
0646     /// Constructor to create a new anonymous tube object with attribute initialization
0647     Tube(double rmin, double rmax, double dz)
0648     {  this->make("", rmin, rmax, dz, 0, 2*M_PI);                   }
0649     /// Constructor to create a new anonymous tube object with attribute initialization
0650     template <typename RMIN, typename RMAX, typename DZ> Tube(RMIN rmin, RMAX rmax, DZ dz)
0651     {  this->make("", _toDouble(rmin), _toDouble(rmax), _toDouble(dz), 0, 2*M_PI);            }
0652     /// Constructor to create a new anonymous tube object with attribute initialization
0653     Tube(double rmin, double rmax, double dz, double endPhi)
0654     {  this->make("", rmin, rmax, dz, 0, endPhi);                   }
0655     /// Constructor to create a new anonymous tube object with attribute initialization
0656     template <typename RMIN, typename RMAX, typename DZ, typename ENDPHI>
0657     Tube(RMIN rmin, RMAX rmax, DZ dz, ENDPHI endPhi)
0658     {  this->make("", _toDouble(rmin), _toDouble(rmax), _toDouble(dz), 0, _toDouble(endPhi)); }
0659     /// Constructor to create a new anonymous tube object with attribute initialization
0660     Tube(double rmin, double rmax, double dz, double startPhi, double endPhi)
0661     {  this->make("", rmin, rmax, dz, startPhi, endPhi);            }
0662     /// Constructor to create a new anonymous tube object with attribute initialization
0663     template <typename RMIN, typename RMAX, typename DZ, typename STARTPHI, typename ENDPHI>
0664     Tube(RMIN rmin, RMAX rmax, DZ dz, STARTPHI startPhi, ENDPHI endPhi)
0665     {  this->make("", _toDouble(rmin), _toDouble(rmax), _toDouble(dz), _toDouble(startPhi), _toDouble(endPhi)); }
0666 
0667     /// Legacy: Constructor to create a new identifiable tube object with attribute initialization
0668     Tube(const std::string& nam, double rmin, double rmax, double dz)
0669     {  this->make(nam, rmin, rmax, dz, 0, 2*M_PI);                  }
0670     /// Constructor to create a new anonymous tube object with attribute initialization
0671     template <typename RMIN, typename RMAX, typename DZ>
0672     Tube(const std::string& nam, RMIN rmin, RMAX rmax, DZ dz)
0673     {  this->make(nam, _toDouble(rmin), _toDouble(rmax), _toDouble(dz), 0, 2*M_PI);          }
0674     /// Legacy: Constructor to create a new identifiable tube object with attribute initialization
0675     Tube(const std::string& nam, double rmin, double rmax, double dz, double endPhi)
0676     {  this->make(nam, rmin, rmax, dz, 0, endPhi);                   }
0677     /// Constructor to create a new anonymous tube object with attribute initialization
0678     template <typename RMIN, typename RMAX, typename DZ, typename ENDPHI>
0679     Tube(const std::string& nam, RMIN rmin, RMAX rmax, DZ dz, ENDPHI endPhi)
0680     {  this->make(nam, _toDouble(rmin), _toDouble(rmax), _toDouble(dz), 0, _toDouble(endPhi)); }
0681     /// Legacy: Constructor to create a new identifiable tube object with attribute initialization
0682     Tube(const std::string& nam, double rmin, double rmax, double dz, double startPhi, double endPhi)
0683     {  this->make(nam, rmin, rmax, dz, startPhi, endPhi);            }
0684     /// Constructor to create a new anonymous tube object with attribute initialization
0685     template <typename RMIN, typename RMAX, typename DZ, typename STARTPHI, typename ENDPHI>
0686     Tube(const std::string& nam, RMIN rmin, RMAX rmax, DZ dz, STARTPHI startPhi, ENDPHI endPhi)
0687     {  this->make(nam, _toDouble(rmin), _toDouble(rmax), _toDouble(dz), _toDouble(startPhi), _toDouble(endPhi)); }
0688 
0689     /// Move Assignment operator
0690     Tube& operator=(Tube&& copy) = default;
0691     /// Copy Assignment operator
0692     Tube& operator=(const Tube& copy) = default;
0693     /// Set the tube dimensions
0694     Tube& setDimensions(double rmin, double rmax, double dz, double startPhi=0.0, double endPhi=2*M_PI);
0695 
0696     /// Accessor: start-phi value
0697     double startPhi() const                { return access()->GetPhi1()*dd4hep::deg; }
0698     /// Accessor: end-phi value
0699     double endPhi() const                  { return access()->GetPhi2()*dd4hep::deg; }
0700     /// Accessor: delta-z value
0701     double dZ() const                      { return access()->GetDz();               }
0702     /// Accessor: r-min value
0703     double rMin() const                    { return access()->GetRmin();             }
0704     /// Accessor: r-max value
0705     double rMax() const                    { return access()->GetRmax();             }
0706   };
0707 
0708   /// Class describing a tube shape of a section of a cut tube segment
0709   /**
0710    *   For any further documentation please see the following ROOT documentation:
0711    *   \see http://root.cern.ch/root/html/TGeoCtub.html
0712    *
0713    *   \author  M.Frank
0714    *   \version 1.0
0715    *   \ingroup DD4HEP_CORE
0716    */
0717   class CutTube : public Solid_type<TGeoCtub> {
0718   protected:
0719     /// Internal helper method to support object construction
0720     void make(const std::string& name,
0721               double rmin, double rmax, double dz, double startPhi, double endPhi,
0722               double lx, double ly, double lz, double tx, double ty, double tz);
0723 
0724   public:
0725     /// Default constructor
0726     CutTube() = default;
0727     /// Move Constructor
0728     CutTube(CutTube&& e) = default;
0729     /// Copy Constructor
0730     CutTube(const CutTube& e) = default;
0731     /// Constructor to be used with an existing object
0732     template <typename Q> CutTube(const Q* p) : Solid_type<Object>(p) {  }
0733     /// Constructor to assign an object
0734     template <typename Q> CutTube(const Handle<Q>& e) : Solid_type<Object>(e) {  }
0735 
0736     /// Constructor to create a new cut-tube object with attribute initialization
0737     CutTube(double rmin, double rmax, double dz, double startPhi, double endPhi,
0738             double lx, double ly, double lz, double tx, double ty, double tz);
0739 
0740     /// Constructor to create a new identifiable cut-tube object with attribute initialization
0741     CutTube(const std::string& name,
0742             double rmin, double rmax, double dz, double startPhi, double endPhi,
0743             double lx, double ly, double lz, double tx, double ty, double tz);
0744 
0745     /// Move Assignment operator
0746     CutTube& operator=(CutTube&& copy) = default;
0747     /// Copy Assignment operator
0748     CutTube& operator=(const CutTube& copy) = default;
0749 
0750     /// Accessor: start-phi value
0751     double startPhi() const                { return access()->GetPhi1()*dd4hep::deg; }
0752     /// Accessor: end-phi value
0753     double endPhi() const                  { return access()->GetPhi2()*dd4hep::deg; }
0754     /// Accessor: delta-z value
0755     double dZ() const                      { return access()->GetDz();               }
0756     /// Accessor: r-min value
0757     double rMin() const                    { return access()->GetRmin();             }
0758     /// Accessor: r-max value
0759     double rMax() const                    { return access()->GetRmax();             }
0760     /// Accessor: lower normal vector of cut plane
0761     std::vector<double> lowNormal()  const { return detail::_make_vector(access()->GetNlow(), 3);  }
0762     /// Accessor: upper normal vector of cut plane
0763     std::vector<double> highNormal() const { return detail::_make_vector(access()->GetNhigh(), 3); }
0764   };
0765 
0766   
0767   /// Class describing a truncated tube shape (CMS'ism)
0768   /**
0769    *   No real correspondence to TGeo. In principle it's a boolean Solid based on a tube.
0770    *   \see http://cmssdt.cern.ch/lxr/source/DetectorDescription/Core/src/TruncTubs.h
0771    *
0772    *   The Solid::dimension() and Solid::setDimension() calls for the TruncatedTube
0773    *   deliver/expect the parameters in the same order as the constructor:
0774    *   (dz, rmin, rmax, startPhi, deltaPhi, cutAtStart, cutAtDelta, cutInside)
0775    *
0776    *   \author  M.Frank
0777    *   \version 1.0
0778    *   \ingroup DD4HEP_CORE
0779    */
0780   class TruncatedTube : public Solid_type<TGeoCompositeShape> {
0781   protected:
0782     /// Internal helper method to support object construction
0783     void make(const std::string& name,
0784               double dz, double rmin, double rmax, double startPhi, double deltaPhi,
0785               double cutAtStart, double cutAtDelta, bool cutInside);
0786 
0787   public:
0788     /// Default constructor
0789     TruncatedTube() = default;
0790     /// Move Constructor
0791     TruncatedTube(TruncatedTube&& e) = default;
0792     /// Copy Constructor
0793     TruncatedTube(const TruncatedTube& e) = default;
0794     /// Constructor to be used with an existing object
0795     template <typename Q> TruncatedTube(const Q* p) : Solid_type<Object>(p) {  }
0796     /// Constructor to assign an object
0797     template <typename Q> TruncatedTube(const Handle<Q>& e) : Solid_type<Object>(e) {  }
0798 
0799     /// Constructor to create a truncated tube object with attribute initialization
0800     TruncatedTube(double dz, double rmin, double rmax, double startPhi, double deltaPhi,
0801                   double cutAtStart, double cutAtDelta, bool cutInside);
0802 
0803     /// Constructor to create a truncated tube object with attribute initialization
0804     TruncatedTube(const std::string& name,
0805                   double dz, double rmin, double rmax, double startPhi, double deltaPhi,
0806                   double cutAtStart, double cutAtDelta, bool cutInside);
0807 
0808     /// Move Assignment operator
0809     TruncatedTube& operator=(TruncatedTube&& copy) = default;
0810     /// Copy Assignment operator
0811     TruncatedTube& operator=(const TruncatedTube& copy) = default;
0812     /// Accessor: z-half value
0813     double dZ() const;
0814     /// Accessor: r-min value
0815     double rMin() const;
0816     /// Accessor: r-max value
0817     double rMax() const;
0818     /// Accessor: start-phi value
0819     double startPhi() const;
0820     /// Accessor: delta-phi value
0821     double deltaPhi() const;
0822     /// Accessor: cut at start value
0823     double cutAtStart() const;
0824     /// Accessor: cut at delta value
0825     double cutAtDelta() const;
0826     /// Accessor: cut-inside value
0827     bool cutInside() const;
0828   };
0829   
0830   /// Class describing a twisted tube shape
0831   /**
0832    *   TGeoEltu - cylindrical tube class. It takes 3 parameters :
0833    *            Semi axis of ellipsis in x and y and half-length dz.
0834    *
0835    *   For any further documentation please see the following ROOT documentation:
0836    *   \see http://root.cern.ch/root/html/TGeoElTu.html
0837    *
0838    *   \author  M.Frank
0839    *   \version 1.0
0840    *   \ingroup DD4HEP_CORE
0841    */
0842   class EllipticalTube : public Solid_type<TGeoEltu> {
0843   protected:
0844     /// Internal helper method to support object construction
0845     void make(const std::string& nam, double a, double b, double dz);
0846 
0847   public:
0848     /// Default constructor
0849     EllipticalTube() = default;
0850     /// Move Constructor
0851     EllipticalTube(EllipticalTube&& e) = default;
0852     /// Copy Constructor
0853     EllipticalTube(const EllipticalTube& e) = default;
0854     /// Constructor to be used with an existing object
0855     template <typename Q> EllipticalTube(const Q* p) : Solid_type<Object>(p) {   }
0856     /// Constructor to assign an object
0857     template <typename Q> EllipticalTube(const Handle<Q>& e) : Solid_type<Object>(e) {   }
0858 
0859     /// Constructor to create a new anonymous tube object with attribute initialization
0860     EllipticalTube(double a, double b, double dz) {  this->make("", a, b, dz);  }
0861     /// Constructor to create a new anonymous tube object with attribute initialization
0862     template <typename A, typename B, typename DZ>
0863     EllipticalTube(const A& a, const B& b, const DZ& dz)
0864     {  this->make("",_toDouble(a), _toDouble(b), _toDouble(dz));     }
0865 
0866     /// Constructor to create a new identified tube object with attribute initialization
0867     EllipticalTube(const std::string& nam, double a, double b, double dz)
0868     {  this->make(nam, a, b, dz);                                    }
0869     /// Constructor to create a new identified tube object with attribute initialization
0870     template <typename A, typename B, typename DZ>
0871     EllipticalTube(const std::string& nam, const A& a, const B& b, const DZ& dz)
0872     {  this->make(nam, _toDouble(a), _toDouble(b), _toDouble(dz));   }
0873 
0874     /// Move Assignment operator
0875     EllipticalTube& operator=(EllipticalTube&& copy) = default;
0876     /// Copy Assignment operator
0877     EllipticalTube& operator=(const EllipticalTube& copy) = default;
0878     /// Set the tube dimensions
0879     EllipticalTube& setDimensions(double a, double b, double dz);
0880 
0881     /// Accessor: delta-z value
0882     double dZ() const                      { return access()->GetDz();               }
0883     /// Accessor: a value (semi axis along x)
0884     double a() const                       { return access()->GetA();                }
0885     /// Accessor: b value (semi axis along y)
0886     double b() const                       { return access()->GetB();                }
0887   };
0888 
0889   /// Class describing a twisted tube shape
0890   /**
0891    *   This is actually no TGeo shape. This implementation is a placeholder
0892    *   for the Geant4 implementation G4TwistedTube.
0893    *   In root it is implemented by a simple tube segment.
0894    *   When converted to geant4 it will become a G4TwistedTube.
0895    *
0896    *
0897    *   \author  M.Frank
0898    *   \version 1.0
0899    *   \ingroup DD4HEP_CORE
0900    */
0901   class TwistedTube : public Solid_type<TGeoTubeSeg> {
0902   protected:
0903     /// Internal helper method to support TwistedTube object construction
0904     void make(const std::string& nam, double twist_angle, double rmin, double rmax,
0905               double zneg, double zpos, int nsegments, double totphi);
0906 
0907   public:
0908     /// Default constructor
0909     TwistedTube() = default;
0910     /// Move Constructor
0911     TwistedTube(TwistedTube&& e) = default;
0912     /// Copy Constructor
0913     TwistedTube(const TwistedTube& e) = default;
0914     /// Constructor to be used with an existing object
0915     template <typename Q> TwistedTube(const Q* p) : Solid_type<Object>(p) {   }
0916     /// Constructor to assign an object
0917     template <typename Q> TwistedTube(const Handle<Q>& e) : Solid_type<Object>(e) {   }
0918 
0919     /// Constructor to create a new anonymous tube object with attribute initialization
0920     TwistedTube(double twist_angle, double rmin, double rmax,
0921                 double dz, double dphi)
0922     {  this->make("", twist_angle, rmin, rmax, -dz, dz, 1, dphi);  }
0923     /// Constructor to create a new anonymous tube object with attribute initialization
0924     TwistedTube(double twist_angle, double rmin, double rmax,
0925                 double dz, int nsegments, double totphi)
0926     {  this->make("", twist_angle, rmin, rmax, -dz, dz, nsegments, totphi);  }
0927     /// Constructor to create a new anonymous tube object with attribute initialization
0928     TwistedTube(double twist_angle, double rmin, double rmax,
0929                 double zneg, double zpos, double totphi)
0930     {  this->make("", twist_angle, rmin, rmax, zneg, zpos, 1, totphi);  }
0931     /// Constructor to create a new anonymous tube object with attribute initialization
0932     TwistedTube(double twist_angle, double rmin, double rmax,
0933                 double zneg, double zpos, int nsegments, double totphi)
0934     {  this->make("", twist_angle, rmin, rmax, zneg, zpos, nsegments, totphi);  }
0935 
0936     /// Constructor to create a new anonymous tube object with attribute initialization
0937     TwistedTube(const std::string& nam, double twist_angle, double rmin, double rmax,
0938                 double dz, double dphi)
0939     {  this->make(nam, twist_angle, rmin, rmax, -dz, dz, 1, dphi);  }
0940     /// Constructor to create a new anonymous tube object with attribute initialization
0941     TwistedTube(const std::string& nam, double twist_angle, double rmin, double rmax,
0942                 double dz, int nsegments, double totphi)
0943     {  this->make(nam, twist_angle, rmin, rmax, -dz, dz, nsegments, totphi);  }
0944     /// Constructor to create a new anonymous tube object with attribute initialization
0945     TwistedTube(const std::string& nam, double twist_angle, double rmin, double rmax,
0946                 double zneg, double zpos, double totphi)
0947     {  this->make(nam, twist_angle, rmin, rmax, zneg, zpos, 1, totphi);  }
0948     /// Constructor to create a new anonymous tube object with attribute initialization
0949     TwistedTube(const std::string& nam, double twist_angle, double rmin, double rmax,
0950                 double zneg, double zpos, int nsegments, double totphi)
0951     {  this->make(nam, twist_angle, rmin, rmax, zneg, zpos, nsegments, totphi);  }
0952 
0953     /// Constructor to create a new identified tube object with attribute initialization
0954     template <typename A, typename B, typename DZ>
0955     TwistedTube(const std::string& nam, const A& a, const B& b, const DZ& dz)
0956     {  this->make(nam, _toDouble(a), _toDouble(b), _toDouble(dz));   }
0957 
0958     /// Move Assignment operator
0959     TwistedTube& operator=(TwistedTube&& copy) = default;
0960     /// Copy Assignment operator
0961     TwistedTube& operator=(const TwistedTube& copy) = default;
0962     /// Set the tube dimensions
0963     TwistedTube& setDimensions(double a, double b, double dz);
0964   };
0965 
0966   /// Class describing a trap shape
0967   /**
0968    *   For any further documentation please see the following ROOT documentation:
0969    *   \see http://root.cern.ch/root/html/TGeoTrap.html
0970    *
0971    *   \author  M.Frank
0972    *   \version 1.0
0973    *   \ingroup DD4HEP_CORE
0974    */
0975   class Trap : public Solid_type<TGeoTrap> {
0976   private:
0977     /// Internal helper method to support object construction
0978     void make(const std::string& name, double pz, double py, double px, double pLTX);
0979   public:
0980     /// Default constructor
0981     Trap() = default;
0982     /// Move Constructor
0983     Trap(Trap&& e) = default;
0984     /// Copy Constructor
0985     Trap(const Trap& e) = default;
0986     /// Constructor to be used with an existing object
0987     template <typename Q> Trap(const Q* p) : Solid_type<Object>(p) { }
0988     /// Constructor to be used when passing an already created object
0989     template <typename Q> Trap(const Handle<Q>& e) : Solid_type<Object>(e) { }
0990 
0991     /// Constructor to create a new anonymous object with attribute initialization
0992     Trap(double z, double theta, double phi,
0993          double h1, double bl1, double tl1, double alpha1,
0994          double h2, double bl2, double tl2, double alpha2);
0995     /// Constructor to create a new anonymous object for right angular wedge from STEP (Se G4 manual for details)
0996     Trap(double pz, double py, double px, double pLTX)
0997     { this->make("", pz,py,px,pLTX);  }
0998     /// Constructor to create a new anonymous object with attribute initialization
0999     template <typename PZ,typename PY,typename PX,typename PLTX> Trap(PZ pz, PY py, PX px, PLTX pLTX)
1000     { this->make("", _toDouble(pz),_toDouble(py),_toDouble(px),_toDouble(pLTX)); }
1001 
1002     /// Constructor to create a new identified object with attribute initialization
1003     Trap(const std::string& name,
1004          double z, double theta, double phi,
1005          double h1, double bl1, double tl1, double alpha1,
1006          double h2, double bl2, double tl2, double alpha2);
1007     /// Constructor to create a new identified object for right angular wedge from STEP (Se G4 manual for details)
1008     Trap(const std::string& nam, double pz, double py, double px, double pLTX)
1009     { this->make(nam, pz,py,px,pLTX);  }
1010     /// Constructor to create a new identified object with attribute initialization
1011     template <typename PZ,typename PY,typename PX,typename PLTX>
1012     Trap(const std::string& nam, PZ pz, PY py, PX px, PLTX pLTX)
1013     { this->make(nam, _toDouble(pz),_toDouble(py),_toDouble(px),_toDouble(pLTX)); }
1014 
1015     /// Move Assignment operator
1016     Trap& operator=(Trap&& copy) = default;
1017     /// Copy Assignment operator
1018     Trap& operator=(const Trap& copy) = default;
1019     /// Set the trap dimensions
1020     Trap& setDimensions(double z, double theta, double phi,
1021                         double h1, double bl1, double tl1, double alpha1,
1022                         double h2, double bl2, double tl2, double alpha2);
1023 
1024     /// Accessor: phi value
1025     double phi() const                     { return access()->GetPhi()*dd4hep::deg;    }
1026     /// Accessor: theta value
1027     double theta() const                   { return access()->GetTheta()*dd4hep::deg;  }
1028     /// Angle between centers of x edges and y axis at low z
1029     double alpha1()  const                 { return access()->GetAlpha1()*dd4hep::deg; }
1030     /// Angle between centers of x edges and y axis at low z
1031     double alpha2()  const                 { return access()->GetAlpha2()*dd4hep::deg; }
1032     /// Half length in x at low z and y low edge
1033     double bottomLow1()  const             { return access()->GetBl1();                }
1034     /// Half length in x at high z and y low edge
1035     double bottomLow2()  const             { return access()->GetBl2();                }
1036     /// Half length in x at low z and y high edge
1037     double topLow1()  const                { return access()->GetTl1();                }
1038     /// Half length in x at high z and y high edge
1039     double topLow2()  const                { return access()->GetTl2();                }
1040     /// Half length in y at low z
1041     double high1()  const                  { return access()->GetH1();                 }
1042     /// Half length in y at high z
1043     double high2()  const                  { return access()->GetH2();                 }
1044     /// Half length in dZ
1045     double dZ()  const                     { return access()->GetDz();                 }
1046   };
1047 
1048   /// Class describing a pseudo trap shape (CMS'ism)
1049   /**
1050    *   No real correspondence to TGeo. In principle it's a boolean Solid based on a tube.
1051    *   \see http://cmssdt.cern.ch/lxr/source/DetectorDescription/Core/src/PseudoTrap.h
1052    *
1053    *   The Solid::dimension() and Solid::setDimension() calls for the PseudoTrap
1054    *   deliver/expect the parameters in the same order as the constructor:
1055    *   (x1, x2, y1, y2, z, radius, minusZ)
1056    *
1057    *   \author  M.Frank
1058    *   \version 1.0
1059    *   \ingroup DD4HEP_CORE
1060    */
1061   class PseudoTrap : public Solid_type<TGeoCompositeShape> {
1062   private:
1063     /// Internal helper method to support object construction
1064     void make(const std::string& nam, double x1, double x2, double y1, double y2, double z, double radius, bool minusZ);
1065   public:
1066     /// Default constructor
1067     PseudoTrap() = default;
1068     /// Move Constructor
1069     PseudoTrap(PseudoTrap&& e) = default;
1070     /// Copy Constructor
1071     PseudoTrap(const PseudoTrap& e) = default;
1072     /// Constructor to be used with an existing object
1073     template <typename Q> PseudoTrap(const Q* p) : Solid_type<Object>(p) { }
1074     /// Constructor to be used when passing an already created object
1075     template <typename Q> PseudoTrap(const Handle<Q>& e) : Solid_type<Object>(e) { }
1076 
1077     /// Constructor to create a new anonymous object with attribute initialization
1078     PseudoTrap(double x1, double x2, double y1, double y2, double z, double radius, bool minusZ)
1079     {  this->make("", x1, x2, y1, y2, z, radius, minusZ);    }
1080 
1081     /// Constructor to create a new identified object with attribute initialization
1082     PseudoTrap(const std::string& nam,
1083                double x1, double x2,
1084                double y1, double y2,
1085                double z,  double radius, bool minusZ)
1086     {  this->make(nam, x1, x2, y1, y2, z, radius, minusZ);    }
1087 
1088     /// Move Assignment operator
1089     PseudoTrap& operator=(PseudoTrap&& copy) = default;
1090     /// Copy Assignment operator
1091     PseudoTrap& operator=(const PseudoTrap& copy) = default;
1092   };
1093 
1094   /// Class describing a Trd1 shape
1095   /**
1096    *   For any further documentation please see the following ROOT documentation:
1097    *   \see http://root.cern.ch/root/html/TGeoTrd1.html
1098    *
1099    *
1100    *   \author  M.Frank
1101    *   \version 1.0
1102    *   \ingroup DD4HEP_CORE
1103    */
1104   class Trd1 : public Solid_type<TGeoTrd1> {
1105   private:
1106     /// Internal helper method to support object construction
1107     void make(const std::string& nam, double x1, double x2, double y, double z);
1108 
1109   public:
1110     /// Default constructor
1111     Trd1() = default;
1112     /// Move Constructor
1113     Trd1(Trd1&& e) = default;
1114     /// Copy Constructor
1115     Trd1(const Trd1& e) = default;
1116     /// Constructor to be used with an existing object
1117     template <typename Q> Trd1(const Q* p) : Solid_type<Object>(p) { }
1118     /// Constructor to be used when passing an already created object
1119     template <typename Q> Trd1(const Handle<Q>& e) : Solid_type<Object>(e) { }
1120 
1121     /// Constructor to create a new anonymous object with attribute initialization
1122     Trd1(double x1, double x2, double y, double z)
1123     { this->make("", x1, x2, y, z);                                           }
1124     /// Constructor to create a new anonymous object with attribute initialization
1125     template <typename X1,typename X2,typename Y,typename Z>
1126     Trd1(X1 x1, X2 x2, Y y, Z z)
1127     { this->make("", _toDouble(x1),_toDouble(x2),_toDouble(y),_toDouble(z));  }
1128 
1129     /// Constructor to create a new anonymous object with attribute initialization
1130     Trd1(const std::string& nam, double x1, double x2, double y, double z)
1131     { this->make(nam, x1, x2, y, z);                                          }
1132     /// Constructor to create a new anonymous object with attribute initialization
1133     template <typename X1,typename X2,typename Y,typename Z>
1134     Trd1(const std::string& nam, X1 x1, X2 x2, Y y, Z z)
1135     { this->make(nam, _toDouble(x1),_toDouble(x2),_toDouble(y),_toDouble(z)); }
1136 
1137     /// Move Assignment operator
1138     Trd1& operator=(Trd1&& copy) = default;
1139     /// Copy Assignment operator
1140     Trd1& operator=(const Trd1& copy) = default;
1141     /// Set the Trd1 dimensions
1142     Trd1& setDimensions(double x1, double x2, double y, double z);
1143 
1144     /// Accessor: delta-x1 value
1145     double dX1() const                     { return access()->GetDx1();              }
1146     /// Accessor: delta-x2 value
1147     double dX2() const                     { return access()->GetDx2();              }
1148     /// Accessor: delta-y value
1149     double dY() const                      { return access()->GetDy();               }
1150     /// Accessor: delta-z value
1151     double dZ() const                      { return access()->GetDz();               }
1152   };
1153   
1154   /// Class describing a Trd2 shape
1155   /**
1156    *   For any further documentation please see the following ROOT documentation:
1157    *   \see http://root.cern.ch/root/html/TGeoTrd2.html
1158    *
1159    *
1160    *   \author  M.Frank
1161    *   \version 1.0
1162    *   \ingroup DD4HEP_CORE
1163    */
1164   class Trd2 : public Solid_type<TGeoTrd2> {
1165   private:
1166     /// Internal helper method to support object construction
1167     void make(const std::string& nam, double x1, double x2, double y1, double y2, double z);
1168 
1169   public:
1170     /// Default constructor
1171     Trd2() = default;
1172     /// Move Constructor
1173     Trd2(Trd2&& e) = default;
1174     /// Copy Constructor
1175     Trd2(const Trd2& e) = default;
1176     /// Constructor to be used with an existing object
1177     template <typename Q> Trd2(const Q* p) : Solid_type<Object>(p) { }
1178     /// Constructor to be used when passing an already created object
1179     template <typename Q> Trd2(const Handle<Q>& e) : Solid_type<Object>(e) { }
1180 
1181     /// Constructor to create a new anonymous object with attribute initialization
1182     Trd2(double x1, double x2, double y1, double y2, double z)
1183     { this->make("", x1, x2, y1, y2, z);  }
1184     /// Constructor to create a new anonymous object with attribute initialization
1185     template <typename X1,typename X2,typename Y1,typename Y2,typename Z>
1186     Trd2(X1 x1, X2 x2, Y1 y1, Y2 y2, Z z)
1187     { this->make("", _toDouble(x1),_toDouble(x2),_toDouble(y1),_toDouble(y2),_toDouble(z)); }
1188 
1189     /// Constructor to create a new identified object with attribute initialization
1190     Trd2(const std::string& nam, double x1, double x2, double y1, double y2, double z)
1191     { this->make(nam, x1, x2, y1, y2, z);  }
1192     /// Constructor to create a new identified object with attribute initialization
1193     template <typename X1,typename X2,typename Y1,typename Y2,typename Z>
1194     Trd2(const std::string& nam, X1 x1, X2 x2, Y1 y1, Y2 y2, Z z)
1195     { this->make(nam, _toDouble(x1),_toDouble(x2),_toDouble(y1),_toDouble(y2),_toDouble(z)); }
1196 
1197     /// Copy Assignment operator
1198     Trd2& operator=(Trd2&& copy) = default;
1199     /// Move Assignment operator
1200     Trd2& operator=(const Trd2& copy) = default;
1201     /// Set the Trd2 dimensions
1202     Trd2& setDimensions(double x1, double x2, double y1, double y2, double z);
1203 
1204     /// Accessor: delta-x1 value
1205     double dX1() const                     { return access()->GetDx1();              }
1206     /// Accessor: delta-x2 value
1207     double dX2() const                     { return access()->GetDx2();              }
1208     /// Accessor: delta-y1 value
1209     double dY1() const                     { return access()->GetDy1();              }
1210     /// Accessor: delta-y2 value
1211     double dY2() const                     { return access()->GetDy2();              }
1212     /// Accessor: delta-z value
1213     double dZ() const                      { return access()->GetDz();               }
1214   };
1215   /// Shortcut name definition
1216   typedef Trd2 Trapezoid;
1217   
1218   /// Class describing a Torus shape
1219   /**
1220    *   For any further documentation please see the following ROOT documentation:
1221    *   \see http://root.cern.ch/root/html/TGeoTorus.html
1222    *
1223    *   \author  M.Frank
1224    *   \version 1.0
1225    *   \ingroup DD4HEP_CORE
1226    */
1227   class Torus : public Solid_type<TGeoTorus> {
1228   private:
1229     /// Internal helper method to support object construction
1230     void make(const std::string& nam, double r, double rmin, double rmax, double startPhi, double deltaPhi);
1231   public:
1232     /// Default constructor
1233     Torus() = default;
1234     /// Move Constructor
1235     Torus(Torus&& e) = default;
1236     /// Copy Constructor
1237     Torus(const Torus& e) = default;
1238     /// Constructor to be used with an existing object
1239     template <typename Q> Torus(const Q* p) : Solid_type<Object>(p) { }
1240     /// Constructor to be used when passing an already created object
1241     template <typename Q> Torus(const Handle<Q>& e) : Solid_type<Object>(e) {  }
1242 
1243     /// Constructor to create a new anonymous object with attribute initialization
1244     template<typename R, typename RMIN, typename RMAX, typename STARTPHI, typename DELTAPHI>
1245     Torus(R r, RMIN rmin, RMAX rmax, STARTPHI startPhi=M_PI, DELTAPHI deltaPhi = 2.*M_PI)
1246     {   this->make("", _toDouble(r),_toDouble(rmin),_toDouble(rmax),_toDouble(startPhi),_toDouble(deltaPhi));  }
1247     /// Constructor to create a new anonymous object with attribute initialization
1248     Torus(double r, double rmin, double rmax, double startPhi=M_PI, double deltaPhi = 2.*M_PI)
1249     {   this->make("", r, rmin, rmax, startPhi, deltaPhi);  }
1250 
1251     /// Constructor to create a new identified object with attribute initialization
1252     template<typename R, typename RMIN, typename RMAX, typename STARTPHI, typename DELTAPHI>
1253     Torus(const std::string& nam, R r, RMIN rmin, RMAX rmax, STARTPHI startPhi=M_PI, DELTAPHI deltaPhi = 2.*M_PI)
1254     {   this->make(nam, _toDouble(r),_toDouble(rmin),_toDouble(rmax),_toDouble(startPhi),_toDouble(deltaPhi));  }
1255     /// Constructor to create a new identified object with attribute initialization
1256     Torus(const std::string& nam, double r, double rmin, double rmax, double startPhi=M_PI, double deltaPhi = 2.*M_PI)
1257     {   this->make(nam, r, rmin, rmax, startPhi, deltaPhi);  }
1258 
1259     /// Move Assignment operator
1260     Torus& operator=(Torus&& copy) = default;
1261     /// Copy Assignment operator
1262     Torus& operator=(const Torus& copy) = default;
1263     /// Set the Torus dimensions
1264     Torus& setDimensions(double r, double rmin, double rmax, double startPhi, double deltaPhi);
1265 
1266     /// Accessor: start-phi value
1267     double startPhi() const                { return access()->GetPhi1()*dd4hep::deg; }
1268     /// Accessor: delta-phi value
1269     double deltaPhi() const                { return access()->GetDphi()*dd4hep::deg; }
1270 
1271     /// Accessor: r value (torus axial radius)
1272     double r() const                       { return access()->GetR();                }
1273     /// Accessor: r-min value (inner radius)
1274     double rMin() const                    { return access()->GetRmin();             }
1275     /// Accessor: r-max value (outer radius)
1276     double rMax() const                    { return access()->GetRmax();             }
1277   };
1278 
1279   /// Class describing a sphere shape
1280   /**
1281    *   For any further documentation please see the following ROOT documentation:
1282    *   \see http://root.cern.ch/root/html/TGeoSphere.html
1283    *
1284    *
1285    *   \author  M.Frank
1286    *   \version 1.0
1287    *   \ingroup DD4HEP_CORE
1288    */
1289   class Sphere : public Solid_type<TGeoSphere> {
1290   protected:
1291     /// Constructor function to be used when creating a new object with attribute initialization
1292     void make(const std::string& nam,
1293               double rmin,       double rmax,
1294               double startTheta, double endTheta,
1295               double startPhi,   double endPhi);
1296   public:
1297     /// Default constructor
1298     Sphere() = default;
1299     /// Move Constructor
1300     Sphere(Sphere&& e) = default;
1301     /// Copy Constructor
1302     Sphere(const Sphere& e) = default;
1303     /// Constructor to be used with an existing object
1304     template <typename Q> Sphere(const Q* p) : Solid_type<Object>(p) { }
1305     /// Constructor to be used when passing an already created object
1306     template <typename Q> Sphere(const Handle<Q>& e) : Solid_type<Object>(e) {  }
1307 
1308     /// Constructor to create a new anonymous object with attribute initialization
1309     Sphere(double rmin,            double rmax,
1310            double startTheta= 0.0, double endTheta = M_PI,
1311            double startPhi  = 0.0, double endPhi   = 2. * M_PI)
1312     {  this->make("", rmin, rmax, startTheta, endTheta, startPhi, endPhi);     }
1313     /// Constructor to create a new anonymous object with generic attribute initialization
1314     template<typename RMIN,              typename RMAX,
1315              typename STARTTHETA=double, typename ENDTHETA=double,
1316              typename STARTPHI=double,   typename ENDPHI=double>
1317     Sphere(RMIN       rmin,              RMAX     rmax,
1318            STARTTHETA startTheta = 0.0,  ENDTHETA endTheta = M_PI,
1319            STARTPHI   startPhi   = 0.0,  ENDPHI   endPhi   = 2. * M_PI)  {
1320       this->make("",
1321                  _toDouble(rmin),       _toDouble(rmax),
1322                  _toDouble(startTheta), _toDouble(endTheta),
1323                  _toDouble(startPhi),   _toDouble(endPhi));
1324     }
1325 
1326     /// Constructor to create a new identified object with attribute initialization
1327     Sphere(const std::string& nam,
1328            double rmin,            double rmax,
1329            double startTheta= 0.0, double endTheta = M_PI,
1330            double startPhi  = 0.0, double endPhi   = 2. * M_PI)
1331     {  this->make(nam, rmin, rmax, startTheta, endTheta, startPhi, endPhi);     }
1332     /// Constructor to create a new identified object with generic attribute initialization
1333     template<typename RMIN,              typename RMAX,
1334              typename STARTTHETA=double, typename ENDTHETA=double,
1335              typename STARTPHI=double,   typename ENDPHI=double>
1336     Sphere(const std::string& nam,
1337            RMIN       rmin,              RMAX     rmax,
1338            STARTTHETA startTheta = 0.0,  ENDTHETA endTheta = M_PI,
1339            STARTPHI   startPhi   = 0.0,  ENDPHI   endPhi   = 2. * M_PI)  {
1340       this->make(nam,
1341                  _toDouble(rmin),       _toDouble(rmax),
1342                  _toDouble(startTheta), _toDouble(endTheta),
1343                  _toDouble(startPhi),   _toDouble(endPhi));
1344     }
1345 
1346     /// Move Assignment operator
1347     Sphere& operator=(Sphere&& copy) = default;
1348     /// Copy Assignment operator
1349     Sphere& operator=(const Sphere& copy) = default;
1350     /// Set the Sphere dimensions
1351     Sphere& setDimensions(double rmin,       double rmax,
1352                           double startTheta, double endTheta,
1353                           double startPhi,   double endPhi);
1354 
1355     /// Accessor: start-phi value
1356     double startPhi() const                { return access()->GetPhi1()*dd4hep::deg;   }
1357     /// Accessor: end-phi value 
1358     double endPhi() const                  { return access()->GetPhi2()*dd4hep::deg;   }
1359     /// Accessor: start-theta value
1360     double startTheta() const              { return access()->GetTheta1()*dd4hep::deg; }
1361     /// Accessor: end-theta value
1362     double endTheta() const                { return access()->GetTheta2()*dd4hep::deg; }
1363     /// Accessor: r-min value
1364     double rMin() const                    { return access()->GetRmin();               }
1365     /// Accessor: r-max value
1366     double rMax() const                    { return access()->GetRmax();               }
1367   };
1368 
1369   /// Class describing a Paraboloid shape
1370   /**
1371    *   For any further documentation please see the following ROOT documentation:
1372    *   \see http://root.cern.ch/root/html/TGeoParaboloid.html
1373    *
1374    *
1375    *   \author  M.Frank
1376    *   \version 1.0
1377    *   \ingroup DD4HEP_CORE
1378    */
1379   class Paraboloid : public Solid_type<TGeoParaboloid> {
1380     /// Constructor function to create a new anonymous object with attribute initialization
1381     void make(const std::string& nam, double r_low, double r_high, double delta_z);
1382   public:
1383     /// Default constructor
1384     Paraboloid() = default;
1385     /// Move Constructor
1386     Paraboloid(Paraboloid&& e) = default;
1387     /// Copy Constructor
1388     Paraboloid(const Paraboloid& e) = default;
1389     /// Constructor to be used with an existing object
1390     template <typename Q> Paraboloid(const Q* p) : Solid_type<Object>(p) { }
1391     /// Constructor to be used when passing an already created object
1392     template <typename Q> Paraboloid(const Handle<Q>& e) : Solid_type<Object>(e) { }
1393 
1394     /// Constructor to create a new anonymous object with attribute initialization
1395     Paraboloid(double r_low, double r_high, double delta_z)
1396     {  this->make("", r_low, r_high, delta_z);  }
1397     /// Constructor to create a new anonymous object with attribute initialization
1398     template<typename R_LOW, typename R_HIGH, typename DELTA_Z>
1399     Paraboloid(R_LOW r_low, R_HIGH r_high, DELTA_Z delta_z)
1400     {  this->make("", _toDouble(r_low), _toDouble(r_high), _toDouble(delta_z));  }
1401 
1402     /// Constructor to create a new identified object with attribute initialization
1403     Paraboloid(const std::string& nam, double r_low, double r_high, double delta_z)
1404     {  this->make(nam, r_low, r_high, delta_z);  }
1405     /// Constructor to create a new identified object with attribute initialization
1406     template<typename R_LOW, typename R_HIGH, typename DELTA_Z>
1407     Paraboloid(const std::string& nam, R_LOW r_low, R_HIGH r_high, DELTA_Z delta_z)
1408     {  this->make(nam, _toDouble(r_low), _toDouble(r_high), _toDouble(delta_z));  }
1409 
1410     /// Move Assignment operator
1411     Paraboloid& operator=(Paraboloid&& copy) = default;
1412     /// Copy Assignment operator
1413     Paraboloid& operator=(const Paraboloid& copy) = default;
1414     /// Set the Paraboloid dimensions
1415     Paraboloid& setDimensions(double r_low, double r_high, double delta_z);
1416 
1417     /// Accessor: delta-z value
1418     double dZ() const                      { return access()->GetDz();               }
1419     /// Accessor: r-min value
1420     double rLow() const                    { return access()->GetRlo();              }
1421     /// Accessor: r-max value
1422     double rHigh() const                   { return access()->GetRhi();              }
1423   };
1424 
1425   /// Class describing a Hyperboloid shape
1426   /**
1427    *   For any further documentation please see the following ROOT documentation:
1428    *   \see http://root.cern.ch/root/html/TGeoHype.html
1429    *
1430    *
1431    *   \author  M.Frank
1432    *   \version 1.0
1433    *   \ingroup DD4HEP_CORE
1434    */
1435   class Hyperboloid : public Solid_type<TGeoHype> {
1436     /// Constructor function to create a new anonymous object with attribute initialization
1437     void make(const std::string& nam, double rin, double stin, double rout, double stout, double dz);
1438   public:
1439     /// Default constructor
1440     Hyperboloid() = default;
1441     /// Move Constructor
1442     Hyperboloid(Hyperboloid&& e) = default;
1443     /// Copy Constructor
1444     Hyperboloid(const Hyperboloid& e) = default;
1445     /// Constructor to be used with an existing object
1446     template <typename Q> Hyperboloid(const Q* p) : Solid_type<Object>(p) {  }
1447     /// Constructor to be used when passing an already created object
1448     template <typename Q> Hyperboloid(const Handle<Q>& e) : Solid_type<Object>(e) {   }
1449 
1450     /// Constructor to create a new anonymous object with attribute initialization
1451     Hyperboloid(double rin, double stin, double rout, double stout, double dz)
1452     { make("", rin, stin, rout, stout, dz);    }
1453     /// Constructor to create a new anonymous object with attribute initialization
1454     template <typename RIN, typename STIN, typename ROUT, typename STOUT, typename DZ>
1455     Hyperboloid(RIN rin, STIN stin, ROUT rout, STOUT stout, DZ dz)
1456     { make("", _toDouble(rin), _toDouble(stin), _toDouble(rout), _toDouble(stout), _toDouble(dz));   }
1457 
1458     /// Constructor to create a new identified object with attribute initialization
1459     Hyperboloid(const std::string& nam, double rin, double stin, double rout, double stout, double dz)
1460     { make(nam, rin, stin, rout, stout, dz);    }
1461     /// Constructor to create a new identified object with attribute initialization
1462     template <typename RIN, typename STIN, typename ROUT, typename STOUT, typename DZ>
1463     Hyperboloid(const std::string& nam, RIN rin, STIN stin, ROUT rout, STOUT stout, DZ dz)
1464     { make(nam, _toDouble(rin), _toDouble(stin), _toDouble(rout), _toDouble(stout), _toDouble(dz));  }
1465 
1466     /// Move Assignment operator
1467     Hyperboloid& operator=(Hyperboloid&& copy) = default;
1468     /// Copy Assignment operator
1469     Hyperboloid& operator=(const Hyperboloid& copy) = default;
1470     /// Set the Hyperboloid dimensions
1471     Hyperboloid& setDimensions(double rin, double stin, double rout, double stout, double dz);
1472 
1473     /// Accessor: delta-z value
1474     double dZ() const                      { return access()->GetDz();               }
1475     /// Accessor: r-min value
1476     double rMin() const                    { return access()->GetRmin();             }
1477     /// Accessor: r-max value
1478     double rMax() const                    { return access()->GetRmax();             }
1479     /// Stereo angle for inner surface
1480     double stereoInner()  const            { return access()->GetStIn();             }
1481     /// Stereo angle for outer surface
1482     double stereoOuter()  const            { return access()->GetStOut();            }
1483   };
1484 
1485   /// Class describing a regular polyhedron shape
1486   /**
1487    *   For any further documentation please see the following ROOT documentation:
1488    *   \see http://root.cern.ch/root/html/TGeoPgon.html
1489    *
1490    *   \author  M.Frank
1491    *   \version 1.0
1492    *   \ingroup DD4HEP_CORE
1493    */
1494   class PolyhedraRegular : public Solid_type<TGeoPgon> {
1495   protected:
1496     /// Helper function to create the polyhedron
1497     void make(const std::string& nam, int nsides, double rmin, double rmax, double zpos, double zneg, double start, double delta);
1498   public:
1499     /// Default constructor
1500     PolyhedraRegular() = default;
1501     /// Move Constructor
1502     PolyhedraRegular(PolyhedraRegular&& e) = default;
1503     /// Copy Constructor
1504     PolyhedraRegular(const PolyhedraRegular& e) = default;
1505     /// Constructor to be used with an existing object
1506     template <typename Q> PolyhedraRegular(const Q* p) : Solid_type<Object>(p) {  }
1507     /// Constructor to be used when passing an already created object
1508     template <typename Q> PolyhedraRegular(const Handle<Q>& e) : Solid_type<Object>(e) {  }
1509 
1510     /// Constructor to create a new object. Phi(start)=0, deltaPhi=2PI, Z-planes at -zlen/2 and +zlen/2
1511     PolyhedraRegular(int nsides, double rmin, double rmax, double zlen)
1512     { this->make("", nsides, rmin, rmax, zlen / 2, -zlen / 2, 0, 2.0*M_PI);           }
1513     /// Constructor to create a new object. Phi(start)=0, deltaPhi=2PI, Z-planes at -zlen/2 and +zlen/2
1514     template <typename NSIDES, typename RMIN, typename RMAX, typename ZLEN>
1515     PolyhedraRegular(NSIDES nsides, RMIN rmin, RMAX rmax, ZLEN zlen)
1516     {
1517       this->make("", _toDouble(nsides),
1518                  _toDouble(rmin), _toDouble(rmax),
1519                  _toDouble(zlen) / 2, -_toDouble(zlen) / 2,
1520                  0, 2.0*M_PI);
1521     }
1522     /// Constructor to create a new object with phi_start, deltaPhi=2PI, Z-planes at -zlen/2 and +zlen/2
1523     PolyhedraRegular(int nsides, double phi_start, double rmin, double rmax, double zlen)
1524     { this->make("", nsides, rmin, rmax, zlen / 2, -zlen / 2, phi_start, 2.0*M_PI);   }
1525     /// Constructor to create a new object with phi_start, deltaPhi=2PI, Z-planes at -zlen/2 and +zlen/2
1526     template <typename NSIDES, typename PHI_START, typename RMIN, typename RMAX, typename ZLEN>
1527     PolyhedraRegular(NSIDES nsides, PHI_START phi_start, RMIN rmin, RMAX rmax, ZLEN zlen)
1528     {
1529       this->make("", _toDouble(nsides),
1530                  _toDouble(rmin), _toDouble(rmax),
1531                  _toDouble(zlen) / 2, -_toDouble(zlen) / 2,
1532                  _toDouble(phi_start), 2.0*M_PI);
1533     }
1534     /// Constructor to create a new object. Phi(start)=0, deltaPhi=2PI, Z-planes a zplanes[0] and zplanes[1]
1535     PolyhedraRegular(int nsides, double rmin, double rmax, double zplanes[2])
1536     { this->make("", nsides, rmin, rmax, zplanes[0], zplanes[1], 0, 2.0*M_PI);        }
1537 
1538     /// Constructor to create a new object. Phi(start)=0, deltaPhi=2PI, Z-planes at -zlen/2 and +zlen/2
1539     PolyhedraRegular(const std::string& nam, int nsides, double rmin, double rmax, double zlen)
1540     { this->make(nam, nsides, rmin, rmax, zlen / 2, -zlen / 2, 0, 2.0*M_PI);          }
1541     /// Constructor to create a new object with phi_start, deltaPhi=2PI, Z-planes at -zlen/2 and +zlen/2
1542     PolyhedraRegular(const std::string& nam, int nsides, double phi_start, double rmin, double rmax, double zlen)
1543     { this->make(nam, nsides, rmin, rmax, zlen / 2, -zlen / 2, phi_start, 2.0*M_PI);  }
1544     /// Constructor to create a new object. Phi(start)=0, deltaPhi=2PI, Z-planes a zplanes[0] and zplanes[1]
1545     PolyhedraRegular(const std::string& nam, int nsides, double rmin, double rmax, double zplanes[2])
1546     { this->make(nam, nsides, rmin, rmax, zplanes[0], zplanes[1], 0, 2.0*M_PI);       }
1547     /// Move Assignment operator
1548     PolyhedraRegular& operator=(PolyhedraRegular&& copy) = default;
1549     /// Copy Assignment operator
1550     PolyhedraRegular& operator=(const PolyhedraRegular& copy) = default;
1551 
1552     /// Accessor: Number of edges
1553     int numEdges()  const                  { return access()->GetNedges();           }
1554     /// Accessor: start-phi value
1555     double startPhi() const                { return access()->GetPhi1()*dd4hep::deg; }
1556     /// Accessor: delta-phi value
1557     double deltaPhi() const                { return access()->GetDphi()*dd4hep::deg; }
1558 
1559     /// Accessor: r-min value
1560     double z(int which) const              { return access()->GetZ(which);           }
1561     /// Accessor: r-min value
1562     double rMin(int which) const           { return access()->GetRmin(which);        }
1563     /// Accessor: r-max value
1564     double rMax(int which) const           { return access()->GetRmax(which);        }
1565 
1566     /// Accessor: vector of z-values for Z-planes value
1567     std::vector<double> zPlaneZ() const    { return detail::zPlaneZ(this);           }
1568     /// Accessor: vector of rMin-values for Z-planes value
1569     std::vector<double> zPlaneRmin() const { return detail::zPlaneRmin(this);        }
1570     /// Accessor: vector of rMax-values for Z-planes value
1571     std::vector<double> zPlaneRmax() const { return detail::zPlaneRmax(this);        }
1572   };
1573 
1574   /// Class describing a regular polyhedron shape
1575   /**
1576    *   For any further documentation please see the following ROOT documentation:
1577    *   \see http://root.cern.ch/root/html/TGeoPgon.html
1578    *
1579    *   \author  M.Frank
1580    *   \version 1.0
1581    *   \ingroup DD4HEP_CORE
1582    */
1583   class Polyhedra : public Solid_type<TGeoPgon> {
1584   protected:
1585     /// Helper function to create the polyhedron
1586     void make(const std::string& nam, int nsides, double start, double delta,
1587               const std::vector<double>& z,
1588               const std::vector<double>& rmin,
1589               const std::vector<double>& rmax);
1590   public:
1591     /// Default constructor
1592     Polyhedra() = default;
1593     /// Move Constructor
1594     Polyhedra(Polyhedra&& e) = default;
1595     /// Copy Constructor
1596     Polyhedra(const Polyhedra& e) = default;
1597     /// Constructor to be used with an existing object
1598     template <typename Q> Polyhedra(const Q* p) : Solid_type<Object>(p)  {         }
1599     /// Constructor to be used when passing an already created object
1600     template <typename Q> Polyhedra(const Handle<Q>& e) : Solid_type<Object>(e) {  }
1601 
1602     /// Constructor to create a new object. Phi(start), deltaPhi, Z-planes at specified positions
1603     Polyhedra(int nsides, double start, double delta,
1604               const std::vector<double>& z, const std::vector<double>& r)   {
1605       std::vector<double> rmin(r.size(), 0e0);
1606       this->make("", nsides, start, delta, z, rmin, r);
1607     }
1608     /// Constructor to create a new object. Phi(start), deltaPhi, Z-planes at specified positions
1609     Polyhedra(int nsides, double start, double delta,
1610               const std::vector<double>& z, const std::vector<double>& rmin, const std::vector<double>& rmax)
1611     {  this->make("", nsides, start, delta, z, rmin, rmax);   }
1612 
1613     /// Constructor to create a new object. Phi(start), deltaPhi, Z-planes at specified positions
1614     Polyhedra(const std::string& nam, int nsides, double start, double delta,
1615               const std::vector<double>& z, const std::vector<double>& r)   {
1616       std::vector<double> rmin(r.size(), 0e0);
1617       this->make(nam, nsides, start, delta, z, rmin, r);
1618     }
1619     /// Constructor to create a new object. Phi(start), deltaPhi, Z-planes at specified positions
1620     Polyhedra(const std::string& nam, int nsides, double start, double delta,
1621               const std::vector<double>& z, const std::vector<double>& rmin, const std::vector<double>& rmax)
1622     {  this->make(nam, nsides, start, delta, z, rmin, rmax);   }
1623     /// Move Assignment operator
1624     Polyhedra& operator=(Polyhedra&& copy) = default;
1625     /// Copy Assignment operator
1626     Polyhedra& operator=(const Polyhedra& copy) = default;
1627 
1628     /// Accessor: Number of edges
1629     int numEdges()  const                  { return access()->GetNedges();           }
1630     /// Accessor: start-phi value
1631     double startPhi() const                { return access()->GetPhi1()*dd4hep::deg; }
1632     /// Accessor: delta-phi value
1633     double deltaPhi() const                { return access()->GetDphi()*dd4hep::deg; }
1634 
1635     /// Accessor: z value
1636     double z(int which) const              { return access()->GetZ(which);           }
1637     /// Accessor: r-min value
1638     double rMin(int which) const           { return access()->GetRmin(which);        }
1639     /// Accessor: r-max value
1640     double rMax(int which) const           { return access()->GetRmax(which);        }
1641 
1642     /// Accessor: vector of z-values for Z-planes value
1643     std::vector<double> zPlaneZ() const    { return detail::zPlaneZ(this);           }
1644     /// Accessor: vector of rMin-values for Z-planes value
1645     std::vector<double> zPlaneRmin() const { return detail::zPlaneRmin(this);        }
1646     /// Accessor: vector of rMax-values for Z-planes value
1647     std::vector<double> zPlaneRmax() const { return detail::zPlaneRmax(this);        }
1648   };
1649 
1650   /// Class describing a extruded polygon shape
1651   /**
1652    *   For any further documentation please see the following ROOT documentation:
1653    *   \see http://root.cern.ch/root/html/TGeoXtru.html
1654    *
1655    *   \author  M.Frank
1656    *   \version 1.0
1657    *   \ingroup DD4HEP_CORE
1658    */
1659   class ExtrudedPolygon : public Solid_type<TGeoXtru> {
1660   protected:
1661     /// Helper function to create the polygon
1662     void make(const std::string& nam,
1663               const std::vector<double> & pt_x,
1664               const std::vector<double> & pt_y,
1665               const std::vector<double> & sec_z,
1666               const std::vector<double> & sec_x,
1667               const std::vector<double> & sec_y,
1668               const std::vector<double> & zscale);
1669   public:
1670     /// Default constructor
1671     ExtrudedPolygon() = default;
1672     /// Move Constructor
1673     ExtrudedPolygon(ExtrudedPolygon&& e) = default;
1674     /// Copy Constructor
1675     ExtrudedPolygon(const ExtrudedPolygon& e) = default;
1676     /// Constructor to be used with an existing object
1677     template <typename Q> ExtrudedPolygon(const Q* p) : Solid_type<Object>(p) {  }
1678     /// Constructor to be used when passing an already created object
1679     template <typename Q> ExtrudedPolygon(const Handle<Q>& e) : Solid_type<Object>(e) {  }
1680 
1681     /// Constructor to create a new object. 
1682     ExtrudedPolygon(const std::vector<double> & pt_x,
1683                     const std::vector<double> & pt_y,
1684                     const std::vector<double> & sec_z,
1685                     const std::vector<double> & sec_x,
1686                     const std::vector<double> & sec_y,
1687                     const std::vector<double> & zscale)
1688     {  this->make("", pt_x, pt_y, sec_z, sec_x, sec_y, zscale);   }
1689 
1690     /// Constructor to create a new identified object. 
1691     ExtrudedPolygon(const std::string& nam,
1692                     const std::vector<double> & pt_x,
1693                     const std::vector<double> & pt_y,
1694                     const std::vector<double> & sec_z,
1695                     const std::vector<double> & sec_x,
1696                     const std::vector<double> & sec_y,
1697                     const std::vector<double> & zscale)
1698     {  this->make(nam, pt_x, pt_y, sec_z, sec_x, sec_y, zscale);   }
1699     /// Move Assignment operator
1700     ExtrudedPolygon& operator=(ExtrudedPolygon&& copy) = default;
1701     /// Copy Assignment operator
1702     ExtrudedPolygon& operator=(const ExtrudedPolygon& copy) = default;
1703 
1704     std::vector<double> x() const   {  return detail::_extract_vector(this->access(), &TGeoXtru::GetX, &TGeoXtru::GetNvert); }
1705     std::vector<double> y() const   {  return detail::_extract_vector(this->access(), &TGeoXtru::GetY, &TGeoXtru::GetNvert); }
1706     std::vector<double> z() const   {  return detail::zPlaneZ(this); }
1707     std::vector<double> zx() const  {  return detail::_extract_vector(this->access(), &TGeoXtru::GetXOffset, &TGeoXtru::GetNz); }
1708     std::vector<double> zy() const  {  return detail::_extract_vector(this->access(), &TGeoXtru::GetYOffset, &TGeoXtru::GetNz); }
1709     std::vector<double> zscale() const { return detail::_extract_vector(this->access(), &TGeoXtru::GetScale, &TGeoXtru::GetNz); }
1710   };
1711 
1712   /// Class describing an arbitray solid defined by 8 vertices.
1713   /**
1714    *   For any further documentation please see the following ROOT documentation:
1715    *   \see http://root.cern.ch/root/html/TGeoArb8.html
1716    *
1717    *   \author  M.Frank
1718    *   \version 1.0
1719    *   \ingroup DD4HEP_CORE
1720    */
1721   class EightPointSolid : public Solid_type<TGeoArb8> {
1722   private:
1723     /// Internal helper method to support object construction
1724     void make(const std::string& nam, double dz, const double* vtx);
1725   public:
1726     /// Default constructor
1727     EightPointSolid() = default;
1728     /// Move Constructor
1729     EightPointSolid(EightPointSolid&& e) = default;
1730     /// Copy Constructor
1731     EightPointSolid(const EightPointSolid& e) = default;
1732     /// Constructor to be used with an existing object
1733     template <typename Q> EightPointSolid(const Q* p) : Solid_type<Object>(p) { }
1734     /// Constructor to be used when passing an already created object
1735     template <typename Q> EightPointSolid(const Handle<Q>& e) : Solid_type<Object>(e) { }
1736 
1737     /// Constructor to create a new anonymous object with attribute initialization
1738     EightPointSolid(double dz, const double* vertices)
1739     { this->make("", dz, vertices);    }
1740 
1741     /// Constructor to create a new identified object with attribute initialization
1742     EightPointSolid(const std::string& nam, double dz, const double* vertices)
1743     { this->make(nam, dz, vertices);   }
1744 
1745     /// Move Assignment operator
1746     EightPointSolid& operator=(EightPointSolid&& copy) = default;
1747     /// Copy Assignment operator
1748     EightPointSolid& operator=(const EightPointSolid& copy) = default;
1749 
1750     /// Accessor: delta-z value
1751     double dZ() const                      { return access()->GetDz();               }
1752     /// Accessor: all vertices as STL vector
1753     std::vector<double> vertices() const   {
1754       const double* values = access()->GetVertices();
1755       return detail::_make_vector(values, 8*2);
1756     }
1757     /// Accessor: single vertex
1758     std::pair<double, double> vertex(int which) const   {
1759       const double* values = access()->GetVertices();
1760       return std::make_pair(values[2*which], values[2*which+1]);
1761     }
1762   };
1763 
1764   /// Class describing a tessellated shape
1765   /**
1766    *   For any further documentation please see the following ROOT documentation:
1767    *   \see http://root.cern.ch/root/html/TGeoTessellated.html
1768    *
1769    *   \author  M.Frank
1770    *   \version 1.0
1771    *   \ingroup DD4HEP_CORE
1772    */
1773   class TessellatedSolid : public Solid_type<TGeoTessellated> {
1774   private:
1775     /// Internal helper method to support object construction
1776     void make(const std::string& nam, int num_facets);
1777     /// Internal helper method to support object construction
1778     void make(const std::string& nam, const std::vector<Object::Vertex_t>& vertices);
1779 
1780   public:
1781     typedef Object::Vertex_t  Vertex;
1782     typedef TGeoFacet         Facet;
1783 
1784   public:
1785     /// Default constructor
1786     TessellatedSolid() = default;
1787     /// Move Constructor
1788     TessellatedSolid(TessellatedSolid&& e) = default;
1789     /// Copy Constructor
1790     TessellatedSolid(const TessellatedSolid& e) = default;
1791     /// Constructor to be used with an existing object
1792     template <typename Q> TessellatedSolid(const Q* p) : Solid_type<Object>(p) { }
1793     /// Constructor to be used when passing an already created object
1794     template <typename Q> TessellatedSolid(const Handle<Q>& e) : Solid_type<Object>(e) { }
1795 
1796     /// Constructor to create a new anonymous object with attribute initialization
1797     TessellatedSolid(int num_facets)
1798     { this->make("", num_facets);    }
1799 
1800     /// Constructor to create a new identified object with attribute initialization
1801     TessellatedSolid(const std::vector<Vertex>& vertices)
1802     { this->make("", vertices);   }
1803 
1804     /// Constructor to create a new anonymous object with attribute initialization
1805     TessellatedSolid(const std::string& nam, int num_facets)
1806     { this->make(nam, num_facets);    }
1807 
1808     /// Constructor to create a new identified object with attribute initialization
1809     TessellatedSolid(const std::string& nam, const std::vector<Vertex>& vertices)
1810     { this->make(nam, vertices);   }
1811 
1812     /// Move Assignment operator
1813     TessellatedSolid& operator=(TessellatedSolid&& copy) = default;
1814     /// Copy Assignment operator
1815     TessellatedSolid& operator=(const TessellatedSolid& copy) = default;
1816     /// Add new facet to the shape
1817     bool addFacet(const Vertex& pt0, const Vertex& pt1, const Vertex& pt2)  const;
1818     /// Add new facet to the shape
1819     bool addFacet(const Vertex& pt0, const Vertex& pt1, const Vertex& pt2, const Vertex& pt3)  const;
1820     /// Add new facet to the shape. Call only if the tessellated shape was constructed with vertices
1821     bool addFacet(const int pt0, const int pt1, const int pt2)  const;
1822     /// Add new facet to the shape. Call only if the tessellated shape was constructed with vertices
1823     bool addFacet(const int pt0, const int pt1, const int pt2, const int pt3)  const;
1824 
1825     /// Access the number of facets in the shape
1826     int num_facet()   const;
1827     /// Access a facet from the built shape
1828     const Facet& facet(int index)    const;
1829     /// Access the number of vertices in the shape
1830     int num_vertex()   const;
1831     /// Access a single vertex from the shape
1832     const Vertex& vertex(int index)    const;
1833   };
1834   
1835   /// Base class describing boolean (=union,intersection,subtraction) solids
1836   /**
1837    *   For any further documentation please see the following ROOT documentation:
1838    *   \see http://root.cern.ch/root/html/TGeoCompositeShape.html
1839    *
1840    *   \author  M.Frank
1841    *   \version 1.0
1842    *   \ingroup DD4HEP_CORE
1843    */
1844   class BooleanSolid : public Solid_type<TGeoCompositeShape> {
1845   public:
1846     /// Default constructor
1847     BooleanSolid() = default;
1848     /// Move Constructor
1849     BooleanSolid(BooleanSolid&& b) = default;
1850     /// Copy Constructor
1851     BooleanSolid(const BooleanSolid& b) = default;
1852     /// Constructor to be used when passing an already created object
1853     template <typename Q>
1854     BooleanSolid(const Handle<Q>& e) : Solid_type<Object>(e) { }
1855     /// Move Assignment operator
1856     BooleanSolid& operator=(BooleanSolid&& copy) = default;
1857     /// Copy Assignment operator
1858     BooleanSolid& operator=(const BooleanSolid& copy) = default;
1859     /// Access right solid of the boolean
1860     Solid rightShape()  const;
1861     /// Access left solid of the boolean
1862     Solid leftShape()  const;
1863     /// Access right positioning matrix of the boolean
1864     const TGeoMatrix* rightMatrix()  const;
1865     /// Access left positioning matrix of the boolean
1866     const TGeoMatrix* leftMatrix()  const;
1867   };
1868 
1869   /// Class describing boolean subtraction solid
1870   /**
1871    *   For any further documentation please see the following ROOT documentation:
1872    *   \see http://root.cern.ch/root/html/TGeoCompositeShape.html
1873    *   \see http://root.cern.ch/root/html/TGeoSubtraction.html
1874    *
1875    *   \author  M.Frank
1876    *   \version 1.0
1877    *   \ingroup DD4HEP_CORE
1878    */
1879   class SubtractionSolid : public BooleanSolid {
1880   public:
1881     /// Default constructor
1882     SubtractionSolid() = default;
1883     /// Move Constructor
1884     SubtractionSolid(SubtractionSolid&& e) = default;
1885     /// Copy Constructor
1886     SubtractionSolid(const SubtractionSolid& e) = default;
1887     /// Constructor to be used when passing an already created object
1888     template <typename Q> SubtractionSolid(const Handle<Q>& e) : BooleanSolid(e) {  }
1889 
1890     /// Constructor to create a new object. Position is identity, Rotation is identity-rotation!
1891     SubtractionSolid(const Solid& shape1, const Solid& shape2);
1892     /// Constructor to create a new object. Placement by position, Rotation is identity-rotation!
1893     SubtractionSolid(const Solid& shape1, const Solid& shape2, const Position& pos);
1894     /// Constructor to create a new object. Placement by a RotationZYX within the mother
1895     SubtractionSolid(const Solid& shape1, const Solid& shape2, const RotationZYX& rot);
1896     /// Constructor to create a new object. Placement by a generic rotoation within the mother
1897     SubtractionSolid(const Solid& shape1, const Solid& shape2, const Rotation3D& rot);
1898     /// Constructor to create a new object. Placement by a generic transformation within the mother
1899     SubtractionSolid(const Solid& shape1, const Solid& shape2, const Transform3D& pos);
1900 
1901     /// Constructor to create a new identified object. Position is identity, Rotation is identity-rotation!
1902     SubtractionSolid(const std::string& name, const Solid& shape1, const Solid& shape2);
1903     /// Constructor to create a new identified object. Placement by position, Rotation is identity-rotation!
1904     SubtractionSolid(const std::string& name, const Solid& shape1, const Solid& shape2, const Position& pos);
1905     /// Constructor to create a new identified object. Placement by a RotationZYX within the mother
1906     SubtractionSolid(const std::string& name, const Solid& shape1, const Solid& shape2, const RotationZYX& rot);
1907     /// Constructor to create a new identified object. Placement by a generic rotoation within the mother
1908     SubtractionSolid(const std::string& name, const Solid& shape1, const Solid& shape2, const Rotation3D& rot);
1909     /// Constructor to create a new identified object. Placement by a generic transformation within the mother
1910     SubtractionSolid(const std::string& name, const Solid& shape1, const Solid& shape2, const Transform3D& pos);
1911     /// Move Assignment operator
1912     SubtractionSolid& operator=(SubtractionSolid&& copy) = default;
1913     /// Copy Assignment operator
1914     SubtractionSolid& operator=(const SubtractionSolid& copy) = default;
1915   };
1916 
1917   /// Class describing boolean union solid
1918   /**
1919    *   For any further documentation please see the following ROOT documentation:
1920    *   \see http://root.cern.ch/root/html/TGeoCompositeShape.html
1921    *   \see http://root.cern.ch/root/html/TGeoUnion.html
1922    *
1923    *   \author  M.Frank
1924    *   \version 1.0
1925    *   \ingroup DD4HEP_CORE
1926    */
1927   class UnionSolid : public BooleanSolid {
1928   public:
1929     /// Default constructor
1930     UnionSolid() = default;
1931     /// Move Constructor
1932     UnionSolid(UnionSolid&& e) = default;
1933     /// Copy Constructor
1934     UnionSolid(const UnionSolid& e) = default;
1935     /// Constructor to be used when passing an already created object
1936     template <typename Q> UnionSolid(const Handle<Q>& e) : BooleanSolid(e) { }
1937 
1938     /// Constructor to create a new object. Position is identity, Rotation is identity-rotation!
1939     UnionSolid(const Solid& shape1, const Solid& shape2);
1940     /// Constructor to create a new object. Placement by position, Rotation is identity-rotation!
1941     UnionSolid(const Solid& shape1, const Solid& shape2, const Position& pos);
1942     /// Constructor to create a new object. Placement by a RotationZYX within the mother
1943     UnionSolid(const Solid& shape1, const Solid& shape2, const RotationZYX& rot);
1944     /// Constructor to create a new object. Placement by a generic rotoation within the mother
1945     UnionSolid(const Solid& shape1, const Solid& shape2, const Rotation3D& rot);
1946     /// Constructor to create a new object. Placement by a generic transformation within the mother
1947     UnionSolid(const Solid& shape1, const Solid& shape2, const Transform3D& pos);
1948 
1949     /// Constructor to create a new identified object. Position is identity, Rotation is identity-rotation!
1950     UnionSolid(const std::string& name, const Solid& shape1, const Solid& shape2);
1951     /// Constructor to create a new identified object. Placement by position, Rotation is identity-rotation!
1952     UnionSolid(const std::string& name, const Solid& shape1, const Solid& shape2, const Position& pos);
1953     /// Constructor to create a new identified object. Placement by a RotationZYX within the mother
1954     UnionSolid(const std::string& name, const Solid& shape1, const Solid& shape2, const RotationZYX& rot);
1955     /// Constructor to create a new identified object. Placement by a generic rotoation within the mother
1956     UnionSolid(const std::string& name, const Solid& shape1, const Solid& shape2, const Rotation3D& rot);
1957     /// Constructor to create a new identified object. Placement by a generic transformation within the mother
1958     UnionSolid(const std::string& name, const Solid& shape1, const Solid& shape2, const Transform3D& pos);
1959     /// Move Assignment operator
1960     UnionSolid& operator=(UnionSolid&& copy) = default;
1961     /// Copy Assignment operator
1962     UnionSolid& operator=(const UnionSolid& copy) = default;
1963   };
1964 
1965   /// Class describing boolean intersection solid
1966   /**
1967    *   For any further documentation please see the following ROOT documentation:
1968    *   \see http://root.cern.ch/root/html/TGeoCompositeShape.html
1969    *   \see http://root.cern.ch/root/html/TGeoIntersection.html
1970    *
1971    *   \author  M.Frank
1972    *   \version 1.0
1973    *   \ingroup DD4HEP_CORE
1974    */
1975   class IntersectionSolid : public BooleanSolid {
1976   public:
1977     /// Default constructor
1978     IntersectionSolid() = default;
1979     /// Move Constructor
1980     IntersectionSolid(IntersectionSolid&& e) = default;
1981     /// Copy Constructor
1982     IntersectionSolid(const IntersectionSolid& e) = default;
1983     /// Constructor to be used when passing an already created object
1984     template <typename Q> IntersectionSolid(const Handle<Q>& e) : BooleanSolid(e) { }
1985 
1986     /// Constructor to create a new object. Position is identity, Rotation is identity-rotation!
1987     IntersectionSolid(const Solid& shape1, const Solid& shape2);
1988     /// Constructor to create a new object. Placement by position, Rotation is identity-rotation!
1989     IntersectionSolid(const Solid& shape1, const Solid& shape2, const Position& pos);
1990     /// Constructor to create a new object. Placement by a RotationZYX within the mother
1991     IntersectionSolid(const Solid& shape1, const Solid& shape2, const RotationZYX& rot);
1992     /// Constructor to create a new object. Placement by a generic rotoation within the mother
1993     IntersectionSolid(const Solid& shape1, const Solid& shape2, const Rotation3D& rot);
1994     /// Constructor to create a new object. Placement by a generic transformation within the mother
1995     IntersectionSolid(const Solid& shape1, const Solid& shape2, const Transform3D& pos);
1996 
1997     /// Constructor to create a new identified object. Position is identity, Rotation is identity-rotation!
1998     IntersectionSolid(const std::string& name, const Solid& shape1, const Solid& shape2);
1999     /// Constructor to create a new identified object. Placement by position, Rotation is identity-rotation!
2000     IntersectionSolid(const std::string& name, const Solid& shape1, const Solid& shape2, const Position& pos);
2001     /// Constructor to create a new identified object. Placement by a RotationZYX within the mother
2002     IntersectionSolid(const std::string& name, const Solid& shape1, const Solid& shape2, const RotationZYX& rot);
2003     /// Constructor to create a new identified object. Placement by a generic rotoation within the mother
2004     IntersectionSolid(const std::string& name, const Solid& shape1, const Solid& shape2, const Rotation3D& rot);
2005     /// Constructor to create a new identified object. Placement by a generic transformation within the mother
2006     IntersectionSolid(const std::string& name, const Solid& shape1, const Solid& shape2, const Transform3D& pos);
2007     /// Move Assignment operator
2008     IntersectionSolid& operator=(IntersectionSolid&& copy) = default;
2009     /// Copy Assignment operator
2010     IntersectionSolid& operator=(const IntersectionSolid& copy) = default;
2011   };
2012 }      /* End namespace dd4hep             */
2013 #endif // DD4HEP_SHAPES_H