DDPixFwdRotation

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
/* 
   == CMS Forward Pixels Geometry ==
   Algorithm for creating rotatuion matrix
*/

#include "FWCore/MessageLogger/interface/MessageLogger.h"
#include "DetectorDescription/Core/interface/DDRotationMatrix.h"
#include "DetectorDescription/Core/interface/DDCurrentNamespace.h"
#include "DetectorDescription/Core/interface/DDSplit.h"
#include "DetectorDescription/Core/interface/DDConstant.h"
#include "DetectorDescription/Core/interface/DDAlgorithm.h"
#include "DetectorDescription/Core/interface/DDAlgorithmFactory.h"
#include "DetectorDescription/Core/interface/DDTransform.h"
#include <CLHEP/Vector/ThreeVector.h>
#include <CLHEP/Vector/Rotation.h>
#include <CLHEP/Vector/RotationInterfaces.h>
#include <CLHEP/Units/GlobalPhysicalConstants.h>
#include <CLHEP/Units/SystemOfUnits.h>

#include <cmath>
#include <algorithm>
#include <map>
#include <string>
#include <vector>

class DDPixFwdRotation : public DDAlgorithm {
public:
  DDPixFwdRotation() {}
  ~DDPixFwdRotation() override = default;

  void initialize(const DDNumericArguments& nArgs,
                  const DDVectorArguments& vArgs,
                  const DDMapArguments& mArgs,
                  const DDStringArguments& sArgs,
                  const DDStringVectorArguments& vsArgs) override;

  void execute(DDCompactView& cpv) override;

private:
  double endcap_;  // +1 for Z Plus endcap disks, -1 for Z Minus endcap disks
  std::string rotNameNippleToCover_;
  std::string rotNameCoverToNipple_;
  std::string rotNameNippleToBody_;
  int nBlades_;              // Number of blades
  double bladeAngle_;        // Angle of blade rotation around axis perpendicular to beam
  double bladeZShift_;       // Shift in Z between the axes of two adjacent blades
  double ancorRadius_;       // Distance from beam line to ancor point defining center of "blade frame"
  double jX_, jY_, jZ_;      // Coordinates of Nipple ancor points J in blade frame
  double kX_, kY_, kZ_;      // Coordinates of Nipple ancor points K in blade frame
  std::string rotNS_;        //Namespace of the rotation matrix
  std::string idNameSpace_;  //Namespace of this and ALL sub-parts
};

void DDPixFwdRotation::initialize(const DDNumericArguments& nArgs,
                                  const DDVectorArguments& vArgs,
                                  const DDMapArguments&,
                                  const DDStringArguments& sArgs,
                                  const DDStringVectorArguments&) {
  // -- Input geometry parameters :  -----------------------------------------------------
  endcap_ = nArgs["Endcap"];
  rotNameNippleToCover_ = sArgs["NippleToCover"];
  rotNameCoverToNipple_ = sArgs["CoverToNipple"];
  rotNameNippleToBody_ = sArgs["NippleToBody"];
  nBlades_ = static_cast<int>(nArgs["Blades"]);  // Number of blades
  bladeAngle_ = nArgs["BladeAngle"];             // Angle of blade rotation around its axis
  bladeZShift_ = nArgs["BladeZShift"];           // Shift in Z between the axes of two adjacent blades
  ancorRadius_ = nArgs["AncorRadius"];  // Distance from beam line to ancor point defining center of "blade frame"
  // Coordinates of Nipple ancor points J and K in "blade frame" :
  jX_ = nArgs["JX"];
  jY_ = nArgs["JY"];
  jZ_ = nArgs["JZ"];
  kX_ = nArgs["KX"];
  kY_ = nArgs["KY"];
  kZ_ = nArgs["KZ"];

  rotNS_ = sArgs["RotationNS"];
  idNameSpace_ = DDCurrentNamespace::ns();

  edm::LogVerbatim("PixelGeom") << "DDPixFwdRotation: Initialize with endcap " << endcap_ << " NameSpace "
                                << idNameSpace_ << ":" << rotNS_ << "\n  nBlades " << nBlades_ << " bladeAngle "
                                << bladeAngle_ << " bladeZShift " << bladeZShift_ << " ancorRadius " << ancorRadius_
                                << " jX|jY|jZ " << jX_ << ":" << jY_ << ":" << jZ_ << " kX|kY|kZ " << kX_ << ":" << kY_
                                << ":" << kZ_;
}

void DDPixFwdRotation::execute(DDCompactView&) {
  // -- Compute Nipple parameters if not already computed :
  double effBladeAngle = endcap_ * bladeAngle_;

  CLHEP::Hep3Vector jC = CLHEP::Hep3Vector(jX_ * endcap_, jY_ + ancorRadius_, jZ_);
  ;  // Point J in the "cover" blade frame
  CLHEP::Hep3Vector kB = CLHEP::Hep3Vector(kX_ * endcap_, kY_ + ancorRadius_, kZ_);
  ;  // PoinladeZShiftladeZShiftladeZShiftt K in the "body" blade frame

  // Z-shift from "cover" to "body" blade frame:
  CLHEP::Hep3Vector tCB(bladeZShift_ * sin(effBladeAngle), 0., bladeZShift_ * cos(effBladeAngle));

  // Rotation from "cover" blade frame into "body" blade frame :
  double deltaPhi = endcap_ * (360. / nBlades_) * CLHEP::deg;
  CLHEP::HepRotation rCB(CLHEP::Hep3Vector(1. * sin(effBladeAngle), 0., 1. * cos(effBladeAngle)), deltaPhi);

  // Transform vector k into "cover" blade frame :
  CLHEP::Hep3Vector kC = rCB * (kB + tCB);

  // Vector JK in the "cover" blade frame:
  CLHEP::Hep3Vector jkC = kC - jC;
  double jkLength = jkC.mag();
  DDConstant JK(DDName("JK", rotNS_), std::make_unique<double>(jkLength));
  edm::LogVerbatim("PixelGeom") << "+++++++++++++++ DDPixFwdRotation: JK Length " << jkLength * CLHEP::mm;

  // Position of the center of a nipple in "cover" blade frame :
  CLHEP::Hep3Vector nippleTranslation((kC + jC) / 2. - CLHEP::Hep3Vector(0., ancorRadius_, 0.));
  edm::LogVerbatim("PixelGeom") << "Child translation : " << nippleTranslation;

  // Rotations from nipple frame to "cover" blade frame and back :
  CLHEP::Hep3Vector vZ(0., 0., 1.);
  CLHEP::Hep3Vector axis = vZ.cross(jkC);
  double angleCover = vZ.angle(jkC);
  edm::LogVerbatim("PixelGeom") << " Angle to Cover: " << angleCover;
  CLHEP::HepRotation rpCN(axis, angleCover);

  DDrot(DDName(rotNameCoverToNipple_, rotNS_),
        std::make_unique<DDRotationMatrix>(
            rpCN.xx(), rpCN.xy(), rpCN.xz(), rpCN.yx(), rpCN.yy(), rpCN.yz(), rpCN.zx(), rpCN.zy(), rpCN.zz()));
  CLHEP::HepRotation rpNC(axis, -angleCover);
  edm::LogVerbatim("PixelGeom") << "DDPixFwdBlades::Defines " << DDName(rotNameCoverToNipple_, rotNS_) << " with "
                                << rpCN;

  DDrot(DDName(rotNameNippleToCover_, rotNS_),
        std::make_unique<DDRotationMatrix>(
            rpNC.xx(), rpNC.xy(), rpNC.xz(), rpNC.yx(), rpNC.yy(), rpNC.yz(), rpNC.zx(), rpNC.zy(), rpNC.zz()));
  edm::LogVerbatim("PixelGeom") << "DDPixFwdBlades::Defines " << DDName(rotNameNippleToCover_, rotNS_) << " with "
                                << rpNC;

  // Rotation from nipple frame to "body" blade frame :
  CLHEP::HepRotation rpNB(rpNC * rCB);
  DDrot(DDName(rotNameNippleToBody_, rotNS_),
        std::make_unique<DDRotationMatrix>(
            rpNB.xx(), rpNB.xy(), rpNB.xz(), rpNB.yx(), rpNB.yy(), rpNB.yz(), rpNB.zx(), rpNB.zy(), rpNB.zz()));
  edm::LogVerbatim("PixelGeom") << "DDPixFwdBlades::Defines " << DDName(rotNameNippleToBody_, rotNS_) << " with "
                                << rpNB;
  edm::LogVerbatim("PixelGeom") << " Angle to body : " << vZ.angle(rpNB * vZ);
}

DEFINE_EDM_PLUGIN(DDAlgorithmFactory, DDPixFwdRotation, "track:DDPixFwdRotation");