CMS 3D CMS Logo

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