Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:22:29

0001 #ifndef MagneticField_GeomBuilder_BaseVolumeHandle_H
0002 #define MagneticField_GeomBuilder_BaseVolumeHandle_H
0003 
0004 /** \class BaseVolumeHandle
0005  * A temporary container to cache info on a six-surface volume during
0006  * the processing. Used to sort, organise, and build shared planes.
0007  * One instance is created for each DDVolume. The parameters of the 
0008  * boundary surfaces are calculated during construction.
0009  *
0010  *  \author N. Amapane - INFN Torino (original developer)
0011  */
0012 
0013 #include "DataFormats/GeometrySurface/interface/Surface.h"
0014 #include "DataFormats/GeometrySurface/interface/ReferenceCounted.h"
0015 #include "DetectorDescription/Core/interface/DDSolidShapes.h"
0016 #include "MagneticField/VolumeGeometry/interface/VolumeSide.h"
0017 
0018 class MagVolume6Faces;
0019 
0020 namespace magneticfield {
0021 
0022   class BaseVolumeHandle {
0023   public:
0024     typedef Surface::GlobalPoint GlobalPoint;
0025     typedef Surface::LocalPoint LocalPoint;
0026     typedef Surface::LocalVector LocalVector;
0027     typedef SurfaceOrientation::GlobalFace Sides;
0028 
0029     BaseVolumeHandle(bool expand2Pi = false, bool debugVal = false);
0030 
0031     // Disallow Default/copy ctor
0032     // (we want to handle only pointers!!!)
0033     BaseVolumeHandle(const BaseVolumeHandle& v) = delete;
0034 
0035     virtual ~BaseVolumeHandle();
0036 
0037     /// Return the center of the volume
0038     const GlobalPoint& center() const;
0039 
0040     /// Distance of (x,y) plane from origin
0041     const double RN() const { return theRN; }
0042 
0043     /// Get the current surface on specified side.
0044     const Surface& surface(int which_side) const;
0045 
0046     const Surface& surface(Sides which_side) const;
0047 
0048     /// Find out if two surfaces are the same physical surface
0049     bool sameSurface(const Surface& s1, Sides which_side, float tolerance = 0.01);
0050 
0051     /// Assign a shared surface perorming sanity checks.
0052     bool setSurface(const Surface& s1, Sides which_side);
0053 
0054     /// if the specified surface has been matched.
0055     bool isPlaneMatched(int which_side) const { return isAssigned[which_side]; }
0056 
0057     int references(int which_side) const {  // FIXME!
0058       /*     return surfaces[which_side]->references(); */
0059       return 0;
0060     }
0061 
0062     /// Name of the volume
0063     std::string name;
0064 
0065     /// Name of magnetic field table file
0066     std::string magFile;
0067 
0068     /// volume number
0069     unsigned short volumeno;
0070 
0071     /// copy number
0072     unsigned short copyno;
0073 
0074     // Phi ranges: Used by: LessDPhiMax; bSector; bSlab::[min|max]Phi();
0075     // MagBSector, MagBRod
0076 
0077     /// Minimum value of phi covered by the volume
0078     // FIXME: actually returns phi of the point on median plane of the -phi
0079     // surface, except for trapezoids where the absoulte min has been implemented
0080     Geom::Phi<float> minPhi() const { return thePhiMin; }
0081 
0082     /// Maximum value of phi covered by the volume
0083     // FIXME: actually returns phi of the point on median plane of the +phi
0084     // surface
0085     Geom::Phi<float> maxPhi() const { return surface(SurfaceOrientation::phiplus).position().phi(); }
0086 
0087     /// Z limits.
0088     // ASSUMPTION: Computed on median Z plane, but this is not a problem since
0089     // all Z planes are orthogonal to the beam line in the current geometry.
0090     double minZ() const { return surface(SurfaceOrientation::zminus).position().z(); }
0091     double maxZ() const { return surface(SurfaceOrientation::zplus).position().z(); }
0092 
0093     /// Minimum R for any point within the volume
0094     double minR() const { return theRMin; }
0095 
0096     /// Position and rotation
0097     const GloballyPositioned<float>* placement() const { return refPlane; }
0098 
0099     /// The surfaces and they orientation, as required to build a MagVolume.
0100     virtual std::vector<VolumeSide> sides() const = 0;
0101 
0102     /// Pointer to the final MagVolume (must be set from outside)
0103     MagVolume6Faces* magVolume;
0104 
0105     bool toExpand() const { return expand; }
0106 
0107     /// Temporary hack to pass information on material. Will eventually be replaced!
0108     bool isIron() const { return isIronFlag; }
0109 
0110     /// The sector for which an interpolator for this class of volumes should be built
0111     int masterSector;
0112 
0113     /// Shape of the solid
0114     virtual DDSolidShape shape() const = 0;
0115 
0116   protected:
0117     typedef ConstReferenceCountingPointer<Surface> RCPS;
0118 
0119     // The volume's six surfaces.
0120     RCPS surfaces[6];
0121     // If the corresponding surface has been assigned to a shared surface.
0122     bool isAssigned[6];
0123 
0124     // Build phi, z surfaces (common for ddtubs and ddcons)
0125     void buildPhiZSurf(double startPhi, double deltaPhi, double zhalf, double rCentr);
0126 
0127     // Distance from the origin along the normal to the volume's zphi plane.
0128     double theRN;
0129 
0130     // Max and min radius for _any_ point within the volume
0131     // FIXME!
0132     double theRMin;
0133     double theRMax;
0134     Geom::Phi<float> thePhiMin;
0135 
0136     // The refPlane is the "main plane" for the solid. It corresponds to the
0137     // x,y plane in the DDD local frame, and defines a frame where the local
0138     // coordinates are the same as in DDD.
0139     GloballyPositioned<float>* refPlane;
0140 
0141     // the center of the volume
0142     GlobalPoint center_;
0143 
0144     // Flag this as a master volume out of wich a 2pi volume should be built
0145     // (e.g. central cylinder); this is taken into account by sides().
0146     bool expand;
0147 
0148     // Temporary hack to keep information on material. Will eventually be replaced!
0149     bool isIronFlag;
0150 
0151     const bool debug;
0152   };
0153 
0154   typedef std::vector<BaseVolumeHandle*> handles;
0155 
0156   // Extractors for precomputed_value_sort() (safe sorting)
0157 
0158   // To sort volumes in Z
0159   struct ExtractZ {
0160     double operator()(const BaseVolumeHandle* v) const { return v->center().z(); }
0161   };
0162 
0163   // To sort volumes in abs(Z)
0164   struct ExtractAbsZ {
0165     double operator()(const BaseVolumeHandle* v) const { return fabs(v->center().z()); }
0166   };
0167 
0168   // To sort volumes in phi (from -pi to pi).
0169   struct ExtractPhi {
0170     double operator()(const BaseVolumeHandle* v) const {
0171       // note that Geom::Phi is implicitly converted to double.
0172       // Periodicity is guaranteed.
0173       return v->center().phi();
0174     }
0175   };
0176 
0177   // To sort volumes based on max phi(from -pi to pi).
0178   struct ExtractPhiMax {
0179     double operator()(const BaseVolumeHandle* v) const {
0180       // note that Geom::Phi is implicitly converted to double.
0181       // Periodicity is guaranteed.
0182       return v->maxPhi();
0183     }
0184   };
0185 
0186   // To sort volumes in R
0187   struct ExtractR {
0188     double operator()(const BaseVolumeHandle* v) const { return v->center().perp(); }
0189   };
0190 
0191   // To sort volumes in RN (distance of (x,y) plane from origin)
0192   struct ExtractRN {
0193     double operator()(const BaseVolumeHandle* v) const { return v->RN(); }
0194   };
0195 
0196   // To sort angles within any range SMALLER THAN PI "counter-clockwise",
0197   // even if the angles cross the pi boundary.
0198   // CAVEAT: // The result is undefined if the input values cover a
0199   // range larger than pi!!!
0200   struct LessDPhi {
0201     bool operator()(double phi1, double phi2) const {
0202       // handle periodicity
0203       return ((Geom::Phi<float>(phi2) - Geom::Phi<float>(phi1)) > 0.);
0204     }
0205   };
0206 
0207   // Compare the Z of volumes.
0208   // Should be used ONLY for std::max_element and std::min_element
0209   // and NEVER for sorting (use precomputed_value_sort with ExtractZ instead)
0210   struct LessZ {
0211     bool operator()(const BaseVolumeHandle* v1, const BaseVolumeHandle* v2) const {
0212       if (v1->center().z() < v2->center().z())
0213         return true;
0214       return false;
0215     }
0216   };
0217 
0218   inline const char* const newln = "\n";
0219   // Newline for formatting debug messages
0220   // Intended to be similar to "endl"
0221 
0222 }  // namespace magneticfield
0223 
0224 #endif