Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:55:25

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     : F.Gaede
0011 //
0012 //==========================================================================
0013 #ifndef DDREC_ISURFACE_H
0014 #define DDREC_ISURFACE_H
0015 
0016 
0017 #include "DDRec/IMaterial.h"
0018 #include "DDRec/Vector2D.h"
0019 #include "DDRec/Vector3D.h"
0020 
0021 #include <bitset>
0022 #include <cmath>
0023 
0024 namespace dd4hep { namespace rec {
0025   
0026   class SurfaceType ;
0027 
0028   typedef long long int long64 ;
0029 
0030 
0031   /** Interface for tracking surfaces. 
0032    * The surface provides access to vectors for u,v,n and the orgigin and
0033    * the inner and outer materials with corresponding thicknesses.
0034    *  
0035    * @author C.Grefe, CERN, F. Gaede, DESY
0036    * @version $Id$
0037    * @date Mar 7 2014
0038    */
0039   class ISurface {
0040     
0041   public:
0042     /// Destructor
0043     virtual ~ISurface() {}
0044     
0045     /// properties of the surface encoded in Type.
0046     virtual const SurfaceType& type() const =0 ;
0047     
0048     /// The id of this surface - corresponds to DetElement id ( or'ed with the placement ids )
0049     virtual long64 id() const =0 ;
0050 
0051     /// Checks if the given point lies within the surface
0052     virtual bool insideBounds(const Vector3D& point, double epsilon=1.e-4) const =0 ;
0053     
0054     /** First direction of measurement U */
0055     virtual Vector3D u( const Vector3D& point = Vector3D() ) const =0 ;
0056     
0057     /** Second direction of measurement V */
0058     virtual Vector3D v(const Vector3D& point = Vector3D() ) const =0 ;
0059     
0060     /// Access to the normal direction at the given point
0061     virtual Vector3D normal(const Vector3D& point = Vector3D() ) const =0 ;
0062     
0063     /** Convert the global position to the local position (u,v) on the surface */
0064     virtual Vector2D globalToLocal( const Vector3D& point) const=0 ;
0065 
0066     /** Convert the local position (u,v) on the surface to the global position*/
0067     virtual Vector3D localToGlobal( const Vector2D& point) const=0 ;
0068 
0069     /** Get Origin of local coordinate system on surface */
0070     virtual const Vector3D& origin() const =0 ;
0071     
0072     /// Access to the material in opposite direction of the normal
0073     virtual const IMaterial& innerMaterial() const =0 ;
0074     
0075     /// Access to the material in direction of the normal
0076     virtual const IMaterial& outerMaterial() const =0 ;
0077     
0078     /** Thickness of inner material */
0079     virtual double innerThickness() const =0 ;
0080     
0081     /** Thickness of outer material */
0082     virtual double outerThickness() const =0 ;
0083     
0084     /** Distance to surface */
0085     virtual double distance(const Vector3D& point ) const =0 ;
0086     
0087     /** The length of the surface along direction u at the origin. For 'regular' boundaries, like rectangles, 
0088      *  this can be used to speed up the computation of inSideBounds.
0089      */
0090     virtual double length_along_u() const=0 ;
0091     
0092     /** The length of the surface along direction v at the origin. For 'regular' boundaries, like rectangles, 
0093      *  this can be used to speed up the computation of inSideBounds.
0094      */
0095     virtual double length_along_v() const=0 ;
0096 
0097   } ;
0098   
0099   //==============================================================================================
0100   /** Minimal interface to provide acces to radius of cylinder surfaces.
0101    * @author F. Gaede, DESY
0102    * @version $Id$
0103    * @date May 6 2014
0104    */
0105   class ICylinder {
0106     
0107   public:
0108     /// Destructor
0109     virtual ~ICylinder() {}
0110     virtual double radius() const=0 ;
0111     virtual Vector3D center() const=0 ;
0112   };
0113   //==============================================================================================
0114   /** Minimal interface to provide acces to radii of conical surfaces.
0115    * @author F. Gaede, DESY
0116    * @version $Id$
0117    * @date Nov 6 2015
0118    */
0119   class ICone {
0120     
0121   public:
0122     /// Destructor
0123     virtual ~ICone() {}
0124     virtual double radius0() const=0 ;
0125     virtual double radius1() const=0 ;
0126     virtual double z0() const=0 ;
0127     virtual double z1() const=0 ;
0128     virtual Vector3D center() const=0 ;
0129   };
0130   
0131   //==============================================================================================
0132   
0133   /** Helper class for describing surface properties.
0134    *  Usage: SurfaceType type(  SurfaceType::Plane, SurfaceType::Sensitive ) ; 
0135    *
0136    * @author F. Gaede, DESY
0137    * @version $Id$
0138    * @date Apr 6 2014
0139    */
0140   class SurfaceType{
0141   
0142   public:
0143     /// enum for defining the bits used to decode the properties
0144     enum SurfaceTypes {
0145       Cylinder = 0,
0146       Plane,
0147       Sensitive,
0148       Helper,
0149       ParallelToZ,
0150       OrthogonalToZ,
0151       Invisible,
0152       Measurement1D,
0153       Cone,
0154       Unbounded
0155     } ;
0156     
0157     ///default c'tor
0158     SurfaceType() : _bits(0) {}
0159 
0160     // c'tor that sets one property
0161     SurfaceType( unsigned prop0 ) : _bits(0) { 
0162       _bits.set( prop0 ) ;
0163     } 
0164     
0165     // c'tor that sets two properties
0166     SurfaceType( unsigned prop0 , unsigned prop1 ) : _bits(0) { 
0167       _bits.set( prop0 ) ;
0168       _bits.set( prop1 ) ;
0169     } 
0170     
0171     // c'tor that sets three properties
0172     SurfaceType( unsigned prop0 , unsigned prop1 , unsigned prop2 ) : _bits(0) { 
0173       _bits.set( prop0 ) ;
0174       _bits.set( prop1 ) ;
0175       _bits.set( prop2 ) ;
0176     } 
0177     
0178     // c'tor that sets four properties
0179     SurfaceType( unsigned prop0 , unsigned prop1 , unsigned prop2, unsigned prop3 ) : _bits(0) { 
0180       _bits.set( prop0 ) ;
0181       _bits.set( prop1 ) ;
0182       _bits.set( prop2 ) ;
0183       _bits.set( prop3 ) ;
0184     } 
0185  
0186    // c'tor that sets five properties
0187     SurfaceType( unsigned prop0 , unsigned prop1 , unsigned prop2, unsigned prop3, unsigned prop4 ) : _bits(0) { 
0188       _bits.set( prop0 ) ;
0189       _bits.set( prop1 ) ;
0190       _bits.set( prop2 ) ;
0191       _bits.set( prop3 ) ;
0192       _bits.set( prop4 ) ;
0193     } 
0194     
0195     /// set the given peorperty
0196     void setProperty( unsigned prop , bool val = true ) { _bits.set( prop , val ) ;  } 
0197     
0198     /// true if surface is sensitive
0199     bool isSensitive() const { return _bits[ SurfaceType::Sensitive ] ; }
0200     
0201     /// true if surface is helper surface for navigation
0202     bool isHelper() const  { return _bits[ SurfaceType::Helper ] ; }
0203     
0204     /// true if this a planar surface
0205     bool isPlane() const { return _bits[ SurfaceType::Plane ] ; } 
0206     
0207     /// true if this a cylindrical surface
0208     bool isCylinder() const { return _bits[ SurfaceType::Cylinder ] ; } 
0209 
0210     /// true if this a conical surface
0211     bool isCone() const { return _bits[ SurfaceType::Cone ] ; } 
0212 
0213     /// true if surface is parallel to Z
0214     bool isParallelToZ() const { return _bits[ SurfaceType::ParallelToZ ] ; } 
0215 
0216     /// true if surface is orthogonal to Z
0217     bool isOrthogonalToZ() const { return _bits[ SurfaceType::OrthogonalToZ ] ; } 
0218    
0219     /// true if surface is not invisble - for drawing only
0220     bool isVisible() const { return ! _bits[ SurfaceType::Invisible ] ; } 
0221 
0222    /// true if this is a cylinder parallel to Z
0223     bool isZCylinder() const  { return ( _bits[ SurfaceType::Cylinder ] &&  _bits[ SurfaceType::ParallelToZ ] ) ; } 
0224 
0225    /// true if this is a cone parallel to Z
0226     bool isZCone() const  { return ( _bits[ SurfaceType::Cone ] &&  _bits[ SurfaceType::ParallelToZ ] ) ; } 
0227 
0228    /// true if this is a plane parallel to Z
0229     bool isZPlane() const  { return ( _bits[ SurfaceType::Plane ] &&  _bits[ SurfaceType::ParallelToZ ] ) ; 
0230     } 
0231     
0232     /// true if this is a plane orthogonal to Z
0233     bool isZDisk() const  { return ( _bits[ SurfaceType::Plane ] &&  _bits[ SurfaceType::OrthogonalToZ ] ) ; } 
0234 
0235     /// true if the measurement is only 1D, i.e. the second direction v is not used
0236     bool isMeasurement1D() const { return _bits[ SurfaceType::Measurement1D ] ; } 
0237 
0238     /// true if the surface is unbounded ( ISurface::insideBounds() does not check volume boundaries)
0239 
0240     bool isUnbounded() const { return  _bits[ SurfaceType::Unbounded ] ; } 
0241 
0242     /// true if all properties of otherType are also true for this type.
0243     bool isSimilar( const SurfaceType& otherType) const {
0244       unsigned long otherBits = otherType._bits.to_ulong() ;
0245       unsigned long theseBits = _bits.to_ulong() ;
0246             //      std::cout << " ** isSimilar : " << otherType._bits.to_string() << " - " << _bits.to_string() << " : " <<  ((  otherBits & theseBits ) == otherBits) << std::endl ;
0247       return (  otherBits & theseBits ) == otherBits ;
0248     }
0249 
0250 
0251     /** True if surface is parallel to Z with accuracy epsilon - result is cached in bit SurfaceType::ParallelToZ */
0252     bool checkParallelToZ( const ISurface& surf , double epsilon=1.e-6 ) const { 
0253       
0254       // if ( _bits[ SurfaceType::ParallelToZ ] ) // set in specific implementation
0255       //    return true ;
0256 
0257       double proj = std::fabs( surf.normal() * Vector3D(0.,0.,1.) )  ;
0258       
0259       _bits.set(  SurfaceType::ParallelToZ , ( proj < epsilon )  ) ;
0260       
0261       // std::cout << " ** checkParallelToZ() - normal : " <<  surf.normal() << " pojection : " << proj 
0262       //        << " _bits[ SurfaceType::ParallelToZ ] = " <<  bool( _bits[ SurfaceType::ParallelToZ ] )
0263       //        << "  ( std::fabs( proj - 1. ) < epsilon )  ) = " <<   ( proj < epsilon ) << std::endl ;
0264 
0265       return  _bits[ SurfaceType::ParallelToZ ] ;
0266     }
0267 
0268     /** True if surface is orthogonal to Z with accuracy epsilon - result is cached in bit SurfaceType::OrthogonalToZ */
0269     bool checkOrthogonalToZ( const ISurface& surf , double epsilon=1.e-6 ) const { 
0270       
0271      // if ( _bits[ SurfaceType::OrthogonalToZ ] ) // set in specific implementation
0272      //     return true ;
0273 
0274       double proj = std::fabs( surf.normal() * Vector3D(0.,0.,1.) )  ;
0275       
0276       _bits.set(  SurfaceType::OrthogonalToZ , ( std::fabs( proj - 1. ) < epsilon )  ) ;
0277       
0278       // std::cout << " ** checkOrthogonalToZ() - normal : " <<  surf.normal() << " pojection : " << proj 
0279       //        << " _bits[ SurfaceType::OrthogonalToZ ] = " << bool( _bits[ SurfaceType::OrthogonalToZ ] ) 
0280       //        << "  ( std::fabs( proj - 1. ) < epsilon )  ) = " <<  ( std::fabs( proj - 1. ) < epsilon ) << std::endl ;
0281 
0282 
0283       return  _bits[ SurfaceType::OrthogonalToZ ] ;
0284     }
0285 
0286 
0287   protected:
0288 
0289     mutable std::bitset<32> _bits ;
0290   } ;
0291 
0292   /// dump SurfaceType operator 
0293   inline std::ostream& operator<<( std::ostream& os , const SurfaceType& t ) {
0294 
0295     os << "sensitive["       << t.isSensitive() 
0296        << "] helper["        << t.isHelper() 
0297        << "] plane["         << t.isPlane()  
0298        << "] cylinder["      << t.isCylinder()  
0299        << "] cone["          << t.isCone()  
0300        << "] parallelToZ["   << t.isParallelToZ()  
0301        << "] orthogonalToZ[" << t.isOrthogonalToZ()  
0302        << "] zCylinder["     << t.isZCylinder() 
0303        << "] zCone["         << t.isZCone() 
0304        << "] zPlane["        << t.isZPlane()  
0305        << "] zDisk["         << t.isZDisk()
0306        << "] unbounded["     << t.isUnbounded()
0307        << "]"  ; 
0308 
0309     return os ;
0310   }
0311 
0312 
0313 
0314   /// dump ISurface operator 
0315   inline std::ostream& operator<<( std::ostream& os , const ISurface& s ) {
0316     
0317     os <<  "   id: " << std::hex << s.id() << std::dec << " type : " << s.type() << std::endl  
0318        <<  "   u : " << s.u() << " v : " << s.v() << " normal : " << s.normal() << " origin : " << s.origin() << std::endl   ;
0319     os <<  "   inner material : " << s.innerMaterial() << "  thickness: " <<  s.innerThickness()  << std::endl  
0320        <<  "   outerMaterial :  " << s.outerMaterial() << "  thickness: " <<  s.outerThickness()  << std::endl   ;
0321 
0322     const ICylinder* cyl = dynamic_cast< const ICylinder* > ( &s ) ;
0323     if( cyl )
0324       os << "   cylinder radius : " << cyl->radius() <<  std::endl   ;
0325 
0326     const ICone* cone = dynamic_cast< const ICone* > ( &s ) ;
0327     if( cone )
0328       os << "   cone radius0: " << cone->radius0() << "   cone radius1: " << cone->radius1()  <<  std::endl   ;
0329 
0330     return os ;
0331   }
0332 
0333 
0334 } } /* namespace rec */
0335 
0336 
0337 
0338 #endif // DDREC_ISURFACE_H