CMS 3D CMS Logo

DDPixFwdBladesNew.cc
Go to the documentation of this file.
1 /*
2  == CMS Forward Pixels Geometry ==
3  Algorithm for placing one-per-blade components.
4 */
5 
18 #include <CLHEP/Vector/ThreeVector.h>
19 #include <CLHEP/Vector/Rotation.h>
20 #include <CLHEP/Vector/RotationInterfaces.h>
21 #include <CLHEP/Units/GlobalPhysicalConstants.h>
22 #include <CLHEP/Units/SystemOfUnits.h>
23 
24 #include <cmath>
25 #include <algorithm>
26 #include <map>
27 #include <string>
28 #include <vector>
29 
30 class DDPixFwdBladesNew : public DDAlgorithm {
31 public:
33  ~DDPixFwdBladesNew() override = default;
34 
35  void initialize(const DDNumericArguments& nArgs,
36  const DDVectorArguments& vArgs,
37  const DDMapArguments& mArgs,
38  const DDStringArguments& sArgs,
39  const DDStringVectorArguments& vsArgs) override;
40 
41  void execute(DDCompactView& cpv) override;
42 
43 private:
44  double endcap_; // +1 for Z Plus endcap disks, -1 for Z Minus endcap disks
45  int nBlades_; // Number of blades
46  double bladeAngle_; // Angle of blade rotation around axis perpendicular to beam
47  double zPlane_; // Common shift in Z for all blades (with respect to disk center plane)
48  double bladeZShift_; // Shift in Z between the axes of two adjacent blades
49  double ancorRadius_; // Distance from beam line to ancor point defining center of "blade frame"
50  int nippleType_; // Flag if it is called frm Nipple (1) or not (0)
51  double jX_, jY_, jZ_; // Coordinates of Nipple ancor points J in blade frame
52  double kX_, kY_, kZ_; // Coordinates of Nipple ancor points K in blade frame
53  std::string flagString_; // String of flags
54  std::string flagSelector_; // Character that means "yes" in flagString
55  std::string childName_; // Child volume name
56  int startCopy_; // First copy number
57  std::vector<double> childTranslationVector_; // Child translation with respect to "blade frame"
58  std::string childRotationName_; // Child rotation with respect to "blade frame"
59  std::string idNameSpace_; //Namespace of this and ALL sub-parts
60 
61  CLHEP::Hep3Vector getTranslation();
62  CLHEP::HepRotation getRotation();
63 };
64 
66  const DDVectorArguments& vArgs,
67  const DDMapArguments&,
68  const DDStringArguments& sArgs,
69  const DDStringVectorArguments&) {
70  endcap_ = nArgs["Endcap"];
71  nBlades_ = static_cast<int>(nArgs["Blades"]); // Number of blades
72  bladeAngle_ = nArgs["BladeAngle"]; // Angle of blade rotation around its axis
73  bladeZShift_ = nArgs["BladeZShift"]; // Shift in Z between the axes of two adjacent blades
74  ancorRadius_ = nArgs["AncorRadius"]; // Distance from beam line to ancor point defining center of "blade frame"
75  // Coordinates of Nipple ancor points J and K in "blade frame" :
76  nippleType_ = static_cast<int>(nArgs["NippleType"]);
77  jX_ = nArgs["JX"];
78  jY_ = nArgs["JY"];
79  jZ_ = nArgs["JZ"];
80  kX_ = nArgs["KX"];
81  kY_ = nArgs["KY"];
82  kZ_ = nArgs["KZ"];
83 
84  flagString_ = sArgs["FlagString"];
85  flagSelector_ = sArgs["FlagSelector"];
86  childName_ = sArgs["Child"];
87  startCopy_ = static_cast<int>(nArgs["StartCopy"]);
88  childTranslationVector_ = vArgs["ChildTranslation"];
89  childRotationName_ = sArgs["ChildRotation"];
90 
92 
93  edm::LogVerbatim("PixelGeom") << "DDPixFwdBladesNew: Initialize with endcap " << endcap_ << " FlagString "
94  << flagString_ << " FlagSelector " << flagSelector_ << " Child " << childName_
95  << " ChildTranslation " << childTranslationVector_[0] << ":"
96  << childTranslationVector_[1] << ":" << childTranslationVector_[2] << " ChildRotation "
97  << childRotationName_ << " NameSpace " << idNameSpace_ << "\n nBlades " << nBlades_
98  << " bladeAngle " << bladeAngle_ << " zPlane " << zPlane_ << " bladeZShift "
99  << bladeZShift_ << " ancorRadius " << ancorRadius_ << " NippleType " << nippleType_
100  << " jX|jY|jZ " << jX_ << ":" << jY_ << ":" << jZ_ << " kX|kY|kZ " << kX_ << ":" << kY_
101  << ":" << kZ_;
102 }
103 
105  // -- Signed versions of blade angle and z-shift :
106 
107  double effBladeAngle = -endcap_ * bladeAngle_;
108  double effBladeZShift = endcap_ * bladeZShift_;
109 
110  // -- Names of mother and child volumes :
111 
112  DDName mother = parent().name();
114 
115  // -- Get translation and rotation from "blade frame" to "child frame", if any :
116 
117  CLHEP::HepRotation childRotMatrix = CLHEP::HepRotation();
118  if (nippleType_ == 1) {
119  childRotMatrix = getRotation();
120  } else if (!childRotationName_.empty()) {
121  DDRotation childRotation =
123  // due to conversion to ROOT::Math::Rotation3D -- Michael Case
124  DD3Vector x, y, z;
125  childRotation.rotation().GetComponents(x, y, z); // these are the orthonormal columns.
126  CLHEP::HepRep3x3 tr(x.X(), y.X(), z.X(), x.Y(), y.Y(), z.Y(), x.Z(), y.Z(), z.Z());
127  childRotMatrix = CLHEP::HepRotation(tr);
128  }
129 
130  CLHEP::Hep3Vector childTranslation =
131  (nippleType_ == 1)
132  ? getTranslation()
134 
135  // Create a matrix for rotation around blade axis (to "blade frame") :
136  CLHEP::HepRotation bladeRotMatrix(CLHEP::Hep3Vector(0., 1., 0.), effBladeAngle);
137 
138  // Cycle over Phi positions, placing copies of the child volume :
139 
140  double deltaPhi = (360. / nBlades_) * CLHEP::deg;
141  int nQuarter = nBlades_ / 4;
142  double zShiftMax = effBladeZShift * ((nQuarter - 1) / 2.);
143  int copy(startCopy_);
144 
145  for (int iBlade = 0; iBlade < nBlades_; iBlade++) {
146  // check if this blade position should be skipped :
147 
148  if (flagString_[iBlade] != flagSelector_[0])
149  continue;
150 
151  // calculate Phi and Z shift for this blade :
152 
153  double phi = (iBlade + 0.5) * deltaPhi - 90. * CLHEP::deg;
154  int iQuarter = iBlade % nQuarter;
155  double zShift = -zShiftMax + iQuarter * effBladeZShift;
156 
157  // compute rotation matrix from mother to blade frame :
158  CLHEP::HepRotation rotMatrix(CLHEP::Hep3Vector(0., 0., 1.), phi);
159  rotMatrix *= bladeRotMatrix;
160 
161  // convert translation vector from blade frame to mother frame, and add Z shift :
162  CLHEP::Hep3Vector translation = rotMatrix(childTranslation + CLHEP::Hep3Vector(0., ancorRadius_, 0.));
163  translation += CLHEP::Hep3Vector(0., 0., zShift + zPlane_);
164 
165  // create DDRotation for placing the child if not already existent :
167  std::string rotstr = mother.name() + DDSplit(childName_).first + std::to_string(copy);
169  edm::LogVerbatim("PixelGeom") << "DDPixFwdBlades: Rotation " << rotstr << " : " << rotation;
170 
171  if (!rotation) {
172  rotMatrix *= childRotMatrix;
173  rotation = DDrot(DDName(rotstr, idNameSpace_),
174  std::make_unique<DDRotationMatrix>(rotMatrix.xx(),
175  rotMatrix.xy(),
176  rotMatrix.xz(),
177  rotMatrix.yx(),
178  rotMatrix.yy(),
179  rotMatrix.yz(),
180  rotMatrix.zx(),
181  rotMatrix.zy(),
182  rotMatrix.zz()));
183  }
184  // position the child :
185 
186  DDTranslation ddtran(translation.x(), translation.y(), translation.z());
187  cpv.position(child, mother, copy, ddtran, rotation);
188  edm::LogVerbatim("PixelGeom") << "DDPixFwdBlades::Position " << child << " copy " << copy << " in " << mother
189  << " with translation " << ddtran << " and rotation " << rotation;
190  ++copy;
191  }
192 
193  // End of cycle over Phi positions
194 }
195 
196 // -- Calculating Nipple parameters : ---------------------------------------------------
197 
199  double effBladeAngle = endcap_ * bladeAngle_;
200 
201  CLHEP::Hep3Vector jC =
202  CLHEP::Hep3Vector(endcap_ * jX_, jY_ + ancorRadius_, jZ_); // Point J in the "cover" blade frame
203  CLHEP::Hep3Vector kB =
204  CLHEP::Hep3Vector(endcap_ * kX_, kY_ + ancorRadius_, kZ_); // Point K in the "body" blade frame
205 
206  // Z-shift from "cover" to "body" blade frame:
207  CLHEP::Hep3Vector tCB(bladeZShift_ * sin(effBladeAngle), 0., bladeZShift_ * cos(effBladeAngle));
208 
209  // Rotation from "cover" blade frame into "body" blade frame :
210  double deltaPhi = endcap_ * (360. / nBlades_) * CLHEP::deg;
211  CLHEP::HepRotation rCB(CLHEP::Hep3Vector(1. * sin(effBladeAngle), 0., 1. * cos(effBladeAngle)), deltaPhi);
212 
213  // Transform vector k into "cover" blade frame :
214  CLHEP::Hep3Vector kC = rCB * (kB + tCB);
215 
216  // Position of the center of a nipple in "cover" blade frame :
217  CLHEP::Hep3Vector nippleTranslation((kC + jC) / 2. - CLHEP::Hep3Vector(0., ancorRadius_, 0.));
218  edm::LogVerbatim("PixelGeom") << "Child translation : " << nippleTranslation;
219  return nippleTranslation;
220 }
221 
222 CLHEP::HepRotation DDPixFwdBladesNew::getRotation() {
223  double effBladeAngle = endcap_ * bladeAngle_;
224 
225  CLHEP::Hep3Vector jC =
226  CLHEP::Hep3Vector(endcap_ * jX_, jY_ + ancorRadius_, jZ_); // Point J in the "cover" blade frame
227  CLHEP::Hep3Vector kB =
228  CLHEP::Hep3Vector(endcap_ * kX_, kY_ + ancorRadius_, kZ_); // Point K in the "body" blade frame
229 
230  // Z-shift from "cover" to "body" blade frame:
231  CLHEP::Hep3Vector tCB(bladeZShift_ * sin(effBladeAngle), 0., bladeZShift_ * cos(effBladeAngle));
232 
233  // Rotation from "cover" blade frame into "body" blade frame :
234  double deltaPhi = endcap_ * (360. / nBlades_) * CLHEP::deg;
235  CLHEP::HepRotation rCB(CLHEP::Hep3Vector(1. * sin(effBladeAngle), 0., 1. * cos(effBladeAngle)), deltaPhi);
236 
237  // Transform vector k into "cover" blade frame :
238  CLHEP::Hep3Vector kC = rCB * (kB + tCB);
239  CLHEP::Hep3Vector jkC = kC - jC;
240  edm::LogVerbatim("PixelGeom") << "+++++++++++++++ DDPixFwdBlades: "
241  << "JK Length " << jkC.mag() * CLHEP::mm;
242 
243  // Rotations from nipple frame to "cover" blade frame and back :
244  CLHEP::Hep3Vector vZ(0., 0., 1.);
245  CLHEP::Hep3Vector axis = vZ.cross(jkC);
246  double angleCover = vZ.angle(jkC);
247  edm::LogVerbatim("PixelGeom") << " Angle to Cover: " << angleCover;
248  CLHEP::HepRotation rpCN(axis, angleCover);
249  return rpCN;
250 }
251 
252 DEFINE_EDM_PLUGIN(DDAlgorithmFactory, DDPixFwdBladesNew, "track:DDPixFwdBladesNew");
Log< level::Info, true > LogVerbatim
void position(const DDLogicalPart &self, const DDLogicalPart &parent, const std::string &copyno, const DDTranslation &trans, const DDRotation &rot, const DDDivision *div=nullptr)
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
DDName is used to identify DDD entities uniquely.
Definition: DDName.h:17
static std::string & ns()
std::string childRotationName_
Compact representation of the geometrical detector hierarchy.
Definition: DDCompactView.h:81
static std::string to_string(const XMLCh *ch)
std::string idNameSpace_
Represents a uniquely identifyable rotation matrix.
Definition: DDTransform.h:57
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double > > DD3Vector
U second(std::pair< T, U > const &p)
const std::string & name() const
Returns the name.
Definition: DDName.cc:41
CLHEP::HepRotation getRotation()
~DDPixFwdBladesNew() override=default
std::string flagSelector_
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
void execute(DDCompactView &cpv) override
DDRotation DDrot(const DDName &name, std::unique_ptr< DDRotationMatrix > rot)
Definition of a uniquely identifiable rotation matrix named by DDName name.
Definition: DDRotation.cc:67
std::vector< double > childTranslationVector_
void initialize(const DDNumericArguments &nArgs, const DDVectorArguments &vArgs, const DDMapArguments &mArgs, const DDStringArguments &sArgs, const DDStringVectorArguments &vsArgs) override
const DDRotationMatrix & rotation() const
Returns the read-only rotation-matrix.
Definition: DDTransform.h:81
#define DEFINE_EDM_PLUGIN(factory, type, name)
CLHEP::Hep3Vector getTranslation()
std::pair< std::string, std::string > DDSplit(const std::string &n)
split into (name,namespace), separator = &#39;:&#39;
Definition: DDSplit.cc:3
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double > > DDTranslation
Definition: DDTranslation.h:7