Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-04-26 22:29:32

0001 /* 
0002    == CMS Forward Pixels Geometry ==
0003    Algorithm for placing one-per-blade components.
0004 */
0005 
0006 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0007 #include "DetectorDescription/Core/interface/DDRotationMatrix.h"
0008 #include "DetectorDescription/Core/interface/DDLogicalPart.h"
0009 #include "DetectorDescription/Core/interface/DDSolid.h"
0010 #include "DetectorDescription/Core/interface/DDMaterial.h"
0011 #include "DetectorDescription/Core/interface/DDCurrentNamespace.h"
0012 #include "DetectorDescription/Core/interface/DDSplit.h"
0013 #include "DetectorDescription/Core/interface/DDConstant.h"
0014 #include "DetectorDescription/Core/interface/DDTypes.h"
0015 #include "DetectorDescription/Core/interface/DDAlgorithm.h"
0016 #include "DetectorDescription/Core/interface/DDAlgorithmFactory.h"
0017 #include "DetectorDescription/Core/interface/DDTransform.h"
0018 #include "CLHEP/Vector/ThreeVector.h"
0019 #include "CLHEP/Vector/Rotation.h"
0020 #include "CLHEP/Vector/RotationInterfaces.h"
0021 #include "CLHEP/Units/GlobalPhysicalConstants.h"
0022 #include "CLHEP/Units/GlobalSystemOfUnits.h"
0023 
0024 #include <cmath>
0025 #include <algorithm>
0026 #include <map>
0027 #include <string>
0028 #include <vector>
0029 
0030 class DDPixFwdBladesNew : public DDAlgorithm {
0031 public:
0032   DDPixFwdBladesNew() {}
0033   ~DDPixFwdBladesNew() override = default;
0034 
0035   void initialize(const DDNumericArguments& nArgs,
0036                   const DDVectorArguments& vArgs,
0037                   const DDMapArguments& mArgs,
0038                   const DDStringArguments& sArgs,
0039                   const DDStringVectorArguments& vsArgs) override;
0040 
0041   void execute(DDCompactView& cpv) override;
0042 
0043 private:
0044   double endcap_;             // +1 for Z Plus endcap disks, -1 for Z Minus endcap disks
0045   int nBlades_;               // Number of blades
0046   double bladeAngle_;         // Angle of blade rotation around axis perpendicular to beam
0047   double zPlane_;             // Common shift in Z for all blades (with respect to disk center plane)
0048   double bladeZShift_;        // Shift in Z between the axes of two adjacent blades
0049   double ancorRadius_;        // Distance from beam line to ancor point defining center of "blade frame"
0050   int nippleType_;            // Flag if it is called frm Nipple (1) or not (0)
0051   double jX_, jY_, jZ_;       // Coordinates of Nipple ancor points J in blade frame
0052   double kX_, kY_, kZ_;       // Coordinates of Nipple ancor points K in blade frame
0053   std::string flagString_;    // String of flags
0054   std::string flagSelector_;  // Character that means "yes" in flagString
0055   std::string childName_;     // Child volume name
0056   int startCopy_;             // First copy number
0057   std::vector<double> childTranslationVector_;  // Child translation with respect to "blade frame"
0058   std::string childRotationName_;               // Child rotation with respect to "blade frame"
0059   std::string idNameSpace_;                     //Namespace of this and ALL sub-parts
0060 
0061   CLHEP::Hep3Vector getTranslation();
0062   CLHEP::HepRotation getRotation();
0063 };
0064 
0065 void DDPixFwdBladesNew::initialize(const DDNumericArguments& nArgs,
0066                                    const DDVectorArguments& vArgs,
0067                                    const DDMapArguments&,
0068                                    const DDStringArguments& sArgs,
0069                                    const DDStringVectorArguments&) {
0070   endcap_ = nArgs["Endcap"];
0071   nBlades_ = static_cast<int>(nArgs["Blades"]);  // Number of blades
0072   bladeAngle_ = nArgs["BladeAngle"];             // Angle of blade rotation around its axis
0073   bladeZShift_ = nArgs["BladeZShift"];           // Shift in Z between the axes of two adjacent blades
0074   ancorRadius_ = nArgs["AncorRadius"];  // Distance from beam line to ancor point defining center of "blade frame"
0075   // Coordinates of Nipple ancor points J and K in "blade frame" :
0076   nippleType_ = static_cast<int>(nArgs["NippleType"]);
0077   jX_ = nArgs["JX"];
0078   jY_ = nArgs["JY"];
0079   jZ_ = nArgs["JZ"];
0080   kX_ = nArgs["KX"];
0081   kY_ = nArgs["KY"];
0082   kZ_ = nArgs["KZ"];
0083 
0084   flagString_ = sArgs["FlagString"];
0085   flagSelector_ = sArgs["FlagSelector"];
0086   childName_ = sArgs["Child"];
0087   startCopy_ = static_cast<int>(nArgs["StartCopy"]);
0088   childTranslationVector_ = vArgs["ChildTranslation"];
0089   childRotationName_ = sArgs["ChildRotation"];
0090 
0091   idNameSpace_ = DDCurrentNamespace::ns();
0092 
0093   edm::LogVerbatim("PixelGeom") << "DDPixFwdBladesNew: Initialize with endcap " << endcap_ << " FlagString "
0094                                 << flagString_ << " FlagSelector " << flagSelector_ << " Child " << childName_
0095                                 << " ChildTranslation " << childTranslationVector_[0] << ":"
0096                                 << childTranslationVector_[1] << ":" << childTranslationVector_[2] << " ChildRotation "
0097                                 << childRotationName_ << " NameSpace " << idNameSpace_ << "\n  nBlades " << nBlades_
0098                                 << " bladeAngle " << bladeAngle_ << " zPlane " << zPlane_ << " bladeZShift "
0099                                 << bladeZShift_ << " ancorRadius " << ancorRadius_ << " NippleType " << nippleType_
0100                                 << " jX|jY|jZ " << jX_ << ":" << jY_ << ":" << jZ_ << " kX|kY|kZ " << kX_ << ":" << kY_
0101                                 << ":" << kZ_;
0102 }
0103 
0104 void DDPixFwdBladesNew::execute(DDCompactView& cpv) {
0105   // -- Signed versions of blade angle and z-shift :
0106 
0107   double effBladeAngle = -endcap_ * bladeAngle_;
0108   double effBladeZShift = endcap_ * bladeZShift_;
0109 
0110   // -- Names of mother and child volumes :
0111 
0112   DDName mother = parent().name();
0113   DDName child(DDSplit(childName_).first, DDSplit(childName_).second);
0114 
0115   // -- Get translation and rotation from "blade frame" to "child frame", if any :
0116 
0117   CLHEP::HepRotation childRotMatrix = CLHEP::HepRotation();
0118   if (nippleType_ == 1) {
0119     childRotMatrix = getRotation();
0120   } else if (!childRotationName_.empty()) {
0121     DDRotation childRotation =
0122         DDRotation(DDName(DDSplit(childRotationName_).first, DDSplit(childRotationName_).second));
0123     // due to conversion to ROOT::Math::Rotation3D -- Michael Case
0124     DD3Vector x, y, z;
0125     childRotation.rotation().GetComponents(x, y, z);  // these are the orthonormal columns.
0126     CLHEP::HepRep3x3 tr(x.X(), y.X(), z.X(), x.Y(), y.Y(), z.Y(), x.Z(), y.Z(), z.Z());
0127     childRotMatrix = CLHEP::HepRotation(tr);
0128   }
0129 
0130   CLHEP::Hep3Vector childTranslation =
0131       (nippleType_ == 1)
0132           ? getTranslation()
0133           : CLHEP::Hep3Vector(childTranslationVector_[0], childTranslationVector_[1], childTranslationVector_[2]);
0134 
0135   // Create a matrix for rotation around blade axis (to "blade frame") :
0136   CLHEP::HepRotation bladeRotMatrix(CLHEP::Hep3Vector(0., 1., 0.), effBladeAngle);
0137 
0138   // Cycle over Phi positions, placing copies of the child volume :
0139 
0140   double deltaPhi = (360. / nBlades_) * CLHEP::deg;
0141   int nQuarter = nBlades_ / 4;
0142   double zShiftMax = effBladeZShift * ((nQuarter - 1) / 2.);
0143   int copy(startCopy_);
0144 
0145   for (int iBlade = 0; iBlade < nBlades_; iBlade++) {
0146     // check if this blade position should be skipped :
0147 
0148     if (flagString_[iBlade] != flagSelector_[0])
0149       continue;
0150 
0151     // calculate Phi and Z shift for this blade :
0152 
0153     double phi = (iBlade + 0.5) * deltaPhi - 90. * CLHEP::deg;
0154     int iQuarter = iBlade % nQuarter;
0155     double zShift = -zShiftMax + iQuarter * effBladeZShift;
0156 
0157     // compute rotation matrix from mother to blade frame :
0158     CLHEP::HepRotation rotMatrix(CLHEP::Hep3Vector(0., 0., 1.), phi);
0159     rotMatrix *= bladeRotMatrix;
0160 
0161     // convert translation vector from blade frame to mother frame, and add Z shift :
0162     CLHEP::Hep3Vector translation = rotMatrix(childTranslation + CLHEP::Hep3Vector(0., ancorRadius_, 0.));
0163     translation += CLHEP::Hep3Vector(0., 0., zShift + zPlane_);
0164 
0165     // create DDRotation for placing the child if not already existent :
0166     DDRotation rotation;
0167     std::string rotstr = mother.name() + DDSplit(childName_).first + std::to_string(copy);
0168     rotation = DDRotation(DDName(rotstr, idNameSpace_));
0169     edm::LogVerbatim("PixelGeom") << "DDPixFwdBlades: Rotation " << rotstr << " : " << rotation;
0170 
0171     if (!rotation) {
0172       rotMatrix *= childRotMatrix;
0173       rotation = DDrot(DDName(rotstr, idNameSpace_),
0174                        std::make_unique<DDRotationMatrix>(rotMatrix.xx(),
0175                                                           rotMatrix.xy(),
0176                                                           rotMatrix.xz(),
0177                                                           rotMatrix.yx(),
0178                                                           rotMatrix.yy(),
0179                                                           rotMatrix.yz(),
0180                                                           rotMatrix.zx(),
0181                                                           rotMatrix.zy(),
0182                                                           rotMatrix.zz()));
0183     }
0184     // position the child :
0185 
0186     DDTranslation ddtran(translation.x(), translation.y(), translation.z());
0187     cpv.position(child, mother, copy, ddtran, rotation);
0188     edm::LogVerbatim("PixelGeom") << "DDPixFwdBlades::Position " << child << " copy " << copy << " in " << mother
0189                                   << " with translation " << ddtran << " and rotation " << rotation;
0190     ++copy;
0191   }
0192 
0193   // End of cycle over Phi positions
0194 }
0195 
0196 // -- Calculating Nipple parameters :  ---------------------------------------------------
0197 
0198 CLHEP::Hep3Vector DDPixFwdBladesNew::getTranslation() {
0199   double effBladeAngle = endcap_ * bladeAngle_;
0200 
0201   CLHEP::Hep3Vector jC =
0202       CLHEP::Hep3Vector(endcap_ * jX_, jY_ + ancorRadius_, jZ_);  // Point J in the "cover" blade frame
0203   CLHEP::Hep3Vector kB =
0204       CLHEP::Hep3Vector(endcap_ * kX_, kY_ + ancorRadius_, kZ_);  // Point K in the "body" blade frame
0205 
0206   // Z-shift from "cover" to "body" blade frame:
0207   CLHEP::Hep3Vector tCB(bladeZShift_ * sin(effBladeAngle), 0., bladeZShift_ * cos(effBladeAngle));
0208 
0209   // Rotation from "cover" blade frame into "body" blade frame :
0210   double deltaPhi = endcap_ * (360. / nBlades_) * CLHEP::deg;
0211   CLHEP::HepRotation rCB(CLHEP::Hep3Vector(1. * sin(effBladeAngle), 0., 1. * cos(effBladeAngle)), deltaPhi);
0212 
0213   // Transform vector k into "cover" blade frame :
0214   CLHEP::Hep3Vector kC = rCB * (kB + tCB);
0215 
0216   // Position of the center of a nipple in "cover" blade frame :
0217   CLHEP::Hep3Vector nippleTranslation((kC + jC) / 2. - CLHEP::Hep3Vector(0., ancorRadius_, 0.));
0218   edm::LogVerbatim("PixelGeom") << "Child translation : " << nippleTranslation;
0219   return nippleTranslation;
0220 }
0221 
0222 CLHEP::HepRotation DDPixFwdBladesNew::getRotation() {
0223   double effBladeAngle = endcap_ * bladeAngle_;
0224 
0225   CLHEP::Hep3Vector jC =
0226       CLHEP::Hep3Vector(endcap_ * jX_, jY_ + ancorRadius_, jZ_);  // Point J in the "cover" blade frame
0227   CLHEP::Hep3Vector kB =
0228       CLHEP::Hep3Vector(endcap_ * kX_, kY_ + ancorRadius_, kZ_);  // Point K in the "body" blade frame
0229 
0230   // Z-shift from "cover" to "body" blade frame:
0231   CLHEP::Hep3Vector tCB(bladeZShift_ * sin(effBladeAngle), 0., bladeZShift_ * cos(effBladeAngle));
0232 
0233   // Rotation from "cover" blade frame into "body" blade frame :
0234   double deltaPhi = endcap_ * (360. / nBlades_) * CLHEP::deg;
0235   CLHEP::HepRotation rCB(CLHEP::Hep3Vector(1. * sin(effBladeAngle), 0., 1. * cos(effBladeAngle)), deltaPhi);
0236 
0237   // Transform vector k into "cover" blade frame :
0238   CLHEP::Hep3Vector kC = rCB * (kB + tCB);
0239   CLHEP::Hep3Vector jkC = kC - jC;
0240   edm::LogVerbatim("PixelGeom") << "+++++++++++++++ DDPixFwdBlades: "
0241                                 << "JK Length " << jkC.mag() * CLHEP::mm;
0242 
0243   // Rotations from nipple frame to "cover" blade frame and back :
0244   CLHEP::Hep3Vector vZ(0., 0., 1.);
0245   CLHEP::Hep3Vector axis = vZ.cross(jkC);
0246   double angleCover = vZ.angle(jkC);
0247   edm::LogVerbatim("PixelGeom") << " Angle to Cover: " << angleCover;
0248   CLHEP::HepRotation rpCN(axis, angleCover);
0249   return rpCN;
0250 }
0251 
0252 DEFINE_EDM_PLUGIN(DDAlgorithmFactory, DDPixFwdBladesNew, "track:DDPixFwdBladesNew");