CMS 3D CMS Logo

DDPixFwdBlades.cc
Go to the documentation of this file.
1 /*
2 == CMS Forward Pixels Geometry ==
3 
4  @version 3.02.01 May 30, 2006
5  @created Dmitry Onoprienko
6 
7  Algorithm for placing one-per-blade components.
8  See header file (DDPixFwdBlades.h) for a detailed description.
9 */
10 
11 #include <cmath>
12 #include <algorithm>
13 
23 #include "CLHEP/Vector/RotationInterfaces.h"
24 #include "CLHEP/Units/GlobalPhysicalConstants.h"
25 #include "CLHEP/Units/GlobalSystemOfUnits.h"
26 
27 
28 // -- Constructors & Destructor : -------------------------------------------------------
29 
32 
33 // Initialization : ---------------------------------------------------------------------
34 
36  const DDVectorArguments & vArgs,
37  const DDMapArguments & ,
38  const DDStringArguments & sArgs,
39  const DDStringVectorArguments & ) {
40 
41  if ( nArgs.find("Endcap") != nArgs.end() ) {
42  endcap = nArgs["Endcap"];
43  } else {
44  endcap = 1.;
45  }
46 
47  if ( sArgs.find("FlagString") != sArgs.end() ) {
48  flagString = sArgs["FlagString"];
49  flagSelector = sArgs["FlagSelector"];
50  } else {
51  flagString = "YYYYYYYYYYYYYYYYYYYYYYYY";
52  flagSelector = "Y";
53  }
54 
55  if ( sArgs.find("Child") != sArgs.end() ) {
56  childName = sArgs["Child"];
57  } else {
58  childName = "";
59  }
60 
61  if ( vArgs.find("ChildTranslation") != vArgs.end() ) {
62  childTranslationVector = vArgs["ChildTranslation"];
63  } else {
64  childTranslationVector = std::vector<double>(3, 0.);
65  }
66 
67  if ( sArgs.find("ChildRotation") != sArgs.end() ) {
68  childRotationName = sArgs["ChildRotation"];
69  } else {
70  childRotationName = "";
71  }
72 
74 
75  // -- Input geometry parameters : -----------------------------------------------------
76 
77  nBlades = 24; // Number of blades
78  bladeAngle = 20.*CLHEP::deg; // Angle of blade rotation around its axis
79  zPlane = 0.; // Common shift in Z for all blades (with respect to disk center plane)
80  bladeZShift = 6.*CLHEP::mm; // Shift in Z between the axes of two adjacent blades
81 
82  ancorRadius = 54.631*CLHEP::mm;// Distance from beam line to ancor point defining center of "blade frame"
83 
84  // Coordinates of Nipple ancor points J and K in "blade frame" :
85 
86  jX = -16.25*CLHEP::mm;
87  jY = 96.50*CLHEP::mm;
88  jZ = 1.25*CLHEP::mm;
89  kX = 16.25*CLHEP::mm;
90  kY = 96.50*CLHEP::mm;
91  kZ = -1.25*CLHEP::mm;
92 
93  // -- Static initialization : -----------------------------------------------------------
94 
95  nippleRotationZPlus = nullptr;
96  nippleRotationZMinus = nullptr;
97  nippleTranslationX = 0.;
98  nippleTranslationY = 0.;
99  nippleTranslationZ = 0.;
100 
101  copyNumbers.clear();
102 
103 }
104 
105 // Execution : --------------------------------------------------------------------------
106 
108 
109  // -- Compute Nipple parameters if not already computed :
110 
111  if (!nippleRotationZPlus) {
112  computeNippleParameters(1.); // Z Plus endcap
113  computeNippleParameters(-1.); // Z Minus endcap
114  }
115  if (childName == "") return;
116 
117  // -- Signed versions of blade angle and z-shift :
118 
119  double effBladeAngle = - endcap * bladeAngle;
120  double effBladeZShift = endcap * bladeZShift;
121 
122  // -- Names of mother and child volumes :
123 
124  DDName mother = parent().name();
126 
127  // -- Get translation and rotation from "blade frame" to "child frame", if any :
128 
129  CLHEP::HepRotation childRotMatrix = CLHEP::HepRotation();
130  if (childRotationName != "") {
132  // due to conversion to ROOT::Math::Rotation3D -- Michael Case
133  DD3Vector x, y, z;
134  childRotation.rotation()->GetComponents(x, y, z); // these are the orthonormal columns.
135  CLHEP::HepRep3x3 tr(x.X(), y.X(), z.X(), x.Y(), y.Y(), z.Y(), x.Z(), y.Z(), z.Z());
136  childRotMatrix = CLHEP::HepRotation(tr);
137  } else if (childName == "pixfwdNipple:PixelForwardNippleZPlus") {
138  childRotMatrix = *nippleRotationZPlus;
139  } else if (childName == "pixfwdNipple:PixelForwardNippleZMinus") {
140  childRotMatrix = *nippleRotationZMinus;
141  }
142 
143  CLHEP::Hep3Vector childTranslation;
144  if (childName == "pixfwdNipple:PixelForwardNippleZPlus") {
145  childTranslation = CLHEP::Hep3Vector(nippleTranslationX, nippleTranslationY, nippleTranslationZ);
146  } else if (childName == "pixfwdNipple:PixelForwardNippleZMinus") {
147  childTranslation = CLHEP::Hep3Vector(-nippleTranslationX, nippleTranslationY, nippleTranslationZ);
148  } else {
149  childTranslation = CLHEP::Hep3Vector(childTranslationVector[0],childTranslationVector[1],childTranslationVector[2]);
150  }
151 
152  // Create a matrix for rotation around blade axis (to "blade frame") :
153 
154  CLHEP::HepRotation bladeRotMatrix(CLHEP::Hep3Vector(0.,1.,0.),effBladeAngle);
155 
156  // Cycle over Phi positions, placing copies of the child volume :
157 
158  double deltaPhi = (360./nBlades)*CLHEP::deg;
159  int nQuarter = nBlades/4;
160  double zShiftMax = effBladeZShift*((nQuarter-1)/2.);
161 
162  for (int iBlade=0; iBlade < nBlades; iBlade++) {
163 
164  // check if this blade position should be skipped :
165 
166  if (flagString[iBlade] != flagSelector[0]) continue;
167  int copy = issueCopyNumber();
168 
169  // calculate Phi and Z shift for this blade :
170 
171  double phi = (iBlade + 0.5) * deltaPhi - 90.*CLHEP::deg;
172  int iQuarter = iBlade % nQuarter;
173  double zShift = - zShiftMax + iQuarter * effBladeZShift;
174 
175  // compute rotation matrix from mother to blade frame :
176 
177  CLHEP::HepRotation rotMatrix(CLHEP::Hep3Vector(0.,0.,1.), phi);
178  rotMatrix *= bladeRotMatrix;
179 
180  // convert translation vector from blade frame to mother frame, and add Z shift :
181 
182  CLHEP::Hep3Vector translation = rotMatrix(childTranslation + CLHEP::Hep3Vector(0., ancorRadius, 0.));
183  translation += CLHEP::Hep3Vector(0., 0., zShift + zPlane);
184 
185  // create DDRotation for placing the child if not already existent :
186 
188  std::string rotstr = DDSplit(mother).first + DDSplit(childName).first + std::to_string(copy);
189  rotation = DDRotation(DDName(rotstr, idNameSpace));
190 
191  if (!rotation) {
192  rotMatrix *= childRotMatrix;
193  DDRotationMatrix* temp = new DDRotationMatrix(rotMatrix.xx(), rotMatrix.xy(), rotMatrix.xz(),
194  rotMatrix.yx(), rotMatrix.yy(), rotMatrix.yz(),
195  rotMatrix.zx(), rotMatrix.zy(), rotMatrix.zz() );
196  rotation = DDrot(DDName(rotstr, idNameSpace), temp);
197  }
198  // position the child :
199 
200  DDTranslation ddtran(translation.x(), translation.y(), translation.z());
201  cpv.position(child, mother, copy, ddtran, rotation);
202  // LogDebug("PixelGeom") << "DDPixFwdBlades: " << child << " Copy " << copy << " positioned in " << mother << " at " << translation << " with rotation " << rotation;
203  }
204 
205  // End of cycle over Phi positions
206 
207 }
208 
209 // -- Helpers : -------------------------------------------------------------------------
210 
212  if (copyNumbers.count(childName) == 0) copyNumbers[childName] = 0;
213  return ++copyNumbers[childName];
214 }
215 
216 
217 // -- Calculating Nipple parameters : ---------------------------------------------------
218 
220 
221  double effBladeAngle = endcap * bladeAngle;
222 
223  CLHEP::Hep3Vector jC; // Point J in the "cover" blade frame
224  CLHEP::Hep3Vector kB; // Point K in the "body" blade frame
225  std::string rotNameNippleToCover;
226  std::string rotNameCoverToNipple;
227  std::string rotNameNippleToBody;
228 
229  if (endcap > 0.) {
230  jC = CLHEP::Hep3Vector(jX, jY + ancorRadius, jZ);
231  kB = CLHEP::Hep3Vector(kX, kY + ancorRadius, kZ);
232  rotNameNippleToCover = "NippleToCoverZPlus";
233  rotNameCoverToNipple = "CoverToNippleZPlus";
234  rotNameNippleToBody = "NippleToBodyZPlus";
235  } else {
236  jC = CLHEP::Hep3Vector(-jX, jY + ancorRadius, jZ);
237  kB = CLHEP::Hep3Vector(-kX, kY + ancorRadius, kZ);
238  rotNameNippleToCover = "NippleToCoverZMinus";
239  rotNameCoverToNipple = "CoverToNippleZMinus";
240  rotNameNippleToBody = "NippleToBodyZMinus";
241  }
242 
243  // Z-shift from "cover" to "body" blade frame:
244 
245  CLHEP::Hep3Vector tCB(bladeZShift*sin(effBladeAngle), 0., bladeZShift*cos(effBladeAngle));
246 
247  // Rotation from "cover" blade frame into "body" blade frame :
248 
249  double deltaPhi = endcap*(360./nBlades)*CLHEP::deg;
250  CLHEP::HepRotation rCB(CLHEP::Hep3Vector(1.*sin(effBladeAngle), 0., 1.*cos(effBladeAngle)), deltaPhi);
251 
252  // Transform vector k into "cover" blade frame :
253 
254  CLHEP::Hep3Vector kC = rCB * (kB + tCB);
255 
256  // Vector JK in the "cover" blade frame:
257 
258  CLHEP::Hep3Vector jkC = kC - jC;
259  double* jkLength = new double(jkC.mag());
260  DDConstant JK(DDName("JK", "pixfwdNipple"), jkLength);
261  LogDebug("PixelGeom") << "+++++++++++++++ DDPixFwdBlades: " << "JK Length " << *jkLength * CLHEP::mm;
262 
263  // Position of the center of a nipple in "cover" blade frame :
264 
265  CLHEP::Hep3Vector nippleTranslation((kC+jC)/2. - CLHEP::Hep3Vector(0., ancorRadius, 0.));
266  if (endcap > 0) {
267  nippleTranslationX = nippleTranslation.x();
268  nippleTranslationY = nippleTranslation.y();
269  nippleTranslationZ = nippleTranslation.z();
270  }
271  LogDebug("PixelGeom") << "Child translation : " << nippleTranslation;
272 
273  // Rotations from nipple frame to "cover" blade frame and back :
274 
275  CLHEP::Hep3Vector vZ(0.,0.,1.);
276  CLHEP::Hep3Vector axis = vZ.cross(jkC);
277  double angleCover = vZ.angle(jkC);
278  LogDebug("PixelGeom") << " Angle to Cover: " << angleCover;
279  CLHEP::HepRotation* rpCN = new CLHEP::HepRotation(axis, angleCover);
280  if (endcap > 0.) {
281  nippleRotationZPlus = rpCN;
282  } else {
283  nippleRotationZMinus = rpCN;
284  }
285  //( endcap > 0. ? nippleRotationZPlus : nippleRotationZMinus ) = rpCN;
286 
287  DDRotationMatrix* ddrpCN = new DDRotationMatrix(rpCN->xx(), rpCN->xy(), rpCN->xz(),
288  rpCN->yx(), rpCN->yy(), rpCN->yz(),
289  rpCN->zx(), rpCN->zy(), rpCN->zz() );
290 
291  DDrot(DDName(rotNameCoverToNipple, "pixfwdNipple"), ddrpCN);
292  CLHEP::HepRotation rpNC(axis, -angleCover);
293  DDRotationMatrix* ddrpNC = new DDRotationMatrix(rpNC.xx(), rpNC.xy(), rpNC.xz(),
294  rpNC.yx(), rpNC.yy(), rpNC.yz(),
295  rpNC.zx(), rpNC.zy(), rpNC.zz() );
296 
297  DDrot(DDName(rotNameNippleToCover, "pixfwdNipple"), ddrpNC);
298 
299  // Rotation from nipple frame to "body" blade frame :
300 
301  CLHEP::HepRotation rpNB( rpNC * rCB );
302  DDRotationMatrix* ddrpNB = new DDRotationMatrix(rpNB.xx(), rpNB.xy(), rpNB.xz(),
303  rpNB.yx(), rpNB.yy(), rpNB.yz(),
304  rpNB.zx(), rpNB.zy(), rpNB.zz() );
305 
306  DDrot(DDName(rotNameNippleToBody, "pixfwdNipple"), ddrpNB);
307  double angleBody = vZ.angle(rpNB * vZ);
308  LogDebug("PixelGeom") << " Angle to body : " << angleBody;
309 }
310 
311 // ---------------------------------------------------------------------------------------
312 
#define LogDebug(id)
const DDRotationMatrix * rotation() const
Returns the read-only rotation-matrix.
Definition: DDTransform.h:91
std::map< std::string, int > copyNumbers
double nippleTranslationZ
def copy(args, dbName)
std::string idNameSpace
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
void computeNippleParameters(double endcap)
DDName is used to identify DDD entities uniquely.
Definition: DDName.h:15
void execute(DDCompactView &cpv) override
static std::string & ns()
Compact representation of the geometrical detector hierarchy.
Definition: DDCompactView.h:83
std::vector< double > childTranslationVector
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double > > DDTranslation
Definition: DDTranslation.h:7
Represents a uniquely identifyable rotation matrix.
Definition: DDTransform.h:67
U second(std::pair< T, U > const &p)
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double > > DD3Vector
A DD Translation is currently implemented with Root Vector3D.
Definition: DDTranslation.h:6
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
double nippleTranslationX
CLHEP::HepRotation * nippleRotationZMinus
CLHEP::HepRotation * nippleRotationZPlus
DDRotation DDrot(const DDName &name, DDRotationMatrix *rot)
Definition of a uniquely identifiable rotation matrix named by DDName name.
Definition: DDRotation.cc:90
void position(const DDLogicalPart &self, const DDLogicalPart &parent, const std::string &copyno, const DDTranslation &trans, const DDRotation &rot, const DDDivision *div=0)
std::string childName
std::string flagString
std::pair< std::string, std::string > DDSplit(const std::string &n)
split into (name,namespace), separator = &#39;:&#39;
Definition: DDSplit.cc:3
~DDPixFwdBlades() override
double nippleTranslationY
a named constant corresponding to the DDL-XML tag <Constant> and <ConstantsVector> ...
Definition: DDConstant.h:17
std::string flagSelector
ROOT::Math::Rotation3D DDRotationMatrix
A DDRotationMatrix is currently implemented with a ROOT Rotation3D.
std::string childRotationName
void initialize(const DDNumericArguments &nArgs, const DDVectorArguments &vArgs, const DDMapArguments &mArgs, const DDStringArguments &sArgs, const DDStringVectorArguments &vsArgs) override