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.empty()) 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.empty()) {
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 = mother.name() + DDSplit(childName).first + std::to_string(copy);
189  rotation = DDRotation(DDName(rotstr, idNameSpace));
190 
191  if (!rotation) {
192  rotMatrix *= childRotMatrix;
193  rotation = DDrot(DDName(rotstr, idNameSpace),
194  std::make_unique<DDRotationMatrix>(rotMatrix.xx(), rotMatrix.xy(), rotMatrix.xz(),
195  rotMatrix.yx(), rotMatrix.yy(), rotMatrix.yz(),
196  rotMatrix.zx(), rotMatrix.zy(), rotMatrix.zz()));
197  }
198  // position the child :
199 
200  DDTranslation ddtran(translation.x(), translation.y(), translation.z());
201  cpv.position(child, mother, copy, ddtran, rotation);
202  }
203 
204  // End of cycle over Phi positions
205 
206 }
207 
208 // -- Helpers : -------------------------------------------------------------------------
209 
211  if (copyNumbers.count(childName) == 0) copyNumbers[childName] = 0;
212  return ++copyNumbers[childName];
213 }
214 
215 
216 // -- Calculating Nipple parameters : ---------------------------------------------------
217 
219 
220  double effBladeAngle = endcap * bladeAngle;
221 
222  CLHEP::Hep3Vector jC; // Point J in the "cover" blade frame
223  CLHEP::Hep3Vector kB; // Point K in the "body" blade frame
224  std::string rotNameNippleToCover;
225  std::string rotNameCoverToNipple;
226  std::string rotNameNippleToBody;
227 
228  if (endcap > 0.) {
229  jC = CLHEP::Hep3Vector(jX, jY + ancorRadius, jZ);
230  kB = CLHEP::Hep3Vector(kX, kY + ancorRadius, kZ);
231  rotNameNippleToCover = "NippleToCoverZPlus";
232  rotNameCoverToNipple = "CoverToNippleZPlus";
233  rotNameNippleToBody = "NippleToBodyZPlus";
234  } else {
235  jC = CLHEP::Hep3Vector(-jX, jY + ancorRadius, jZ);
236  kB = CLHEP::Hep3Vector(-kX, kY + ancorRadius, kZ);
237  rotNameNippleToCover = "NippleToCoverZMinus";
238  rotNameCoverToNipple = "CoverToNippleZMinus";
239  rotNameNippleToBody = "NippleToBodyZMinus";
240  }
241 
242  // Z-shift from "cover" to "body" blade frame:
243 
244  CLHEP::Hep3Vector tCB(bladeZShift*sin(effBladeAngle), 0., bladeZShift*cos(effBladeAngle));
245 
246  // Rotation from "cover" blade frame into "body" blade frame :
247 
248  double deltaPhi = endcap*(360./nBlades)*CLHEP::deg;
249  CLHEP::HepRotation rCB(CLHEP::Hep3Vector(1.*sin(effBladeAngle), 0., 1.*cos(effBladeAngle)), deltaPhi);
250 
251  // Transform vector k into "cover" blade frame :
252 
253  CLHEP::Hep3Vector kC = rCB * (kB + tCB);
254 
255  // Vector JK in the "cover" blade frame:
256 
257  CLHEP::Hep3Vector jkC = kC - jC;
258  double jkLength = jkC.mag();
259  DDConstant JK(DDName("JK", "pixfwdNipple"), std::make_unique<double>( jkLength ));
260  LogDebug("PixelGeom") << "+++++++++++++++ DDPixFwdBlades: " << "JK Length " << jkLength * CLHEP::mm;
261 
262  // Position of the center of a nipple in "cover" blade frame :
263 
264  CLHEP::Hep3Vector nippleTranslation((kC+jC)/2. - CLHEP::Hep3Vector(0., ancorRadius, 0.));
265  if (endcap > 0) {
266  nippleTranslationX = nippleTranslation.x();
267  nippleTranslationY = nippleTranslation.y();
268  nippleTranslationZ = nippleTranslation.z();
269  }
270  LogDebug("PixelGeom") << "Child translation : " << nippleTranslation;
271 
272  // Rotations from nipple frame to "cover" blade frame and back :
273 
274  CLHEP::Hep3Vector vZ(0.,0.,1.);
275  CLHEP::Hep3Vector axis = vZ.cross(jkC);
276  double angleCover = vZ.angle(jkC);
277  LogDebug("PixelGeom") << " Angle to Cover: " << angleCover;
278  CLHEP::HepRotation* rpCN = new CLHEP::HepRotation(axis, angleCover);
279  if (endcap > 0.) {
280  nippleRotationZPlus = rpCN;
281  } else {
282  nippleRotationZMinus = rpCN;
283  }
284  //( endcap > 0. ? nippleRotationZPlus : nippleRotationZMinus ) = rpCN;
285 
286  DDrot(DDName(rotNameCoverToNipple, "pixfwdNipple"),
287  std::make_unique<DDRotationMatrix>( rpCN->xx(), rpCN->xy(), rpCN->xz(),
288  rpCN->yx(), rpCN->yy(), rpCN->yz(),
289  rpCN->zx(), rpCN->zy(), rpCN->zz()));
290  CLHEP::HepRotation rpNC(axis, -angleCover);
291 
292  DDrot(DDName(rotNameNippleToCover, "pixfwdNipple"),
293  std::make_unique<DDRotationMatrix>( rpNC.xx(), rpNC.xy(), rpNC.xz(),
294  rpNC.yx(), rpNC.yy(), rpNC.yz(),
295  rpNC.zx(), rpNC.zy(), rpNC.zz()));
296 
297  // Rotation from nipple frame to "body" blade frame :
298 
299  CLHEP::HepRotation rpNB( rpNC * rCB );
300 
301  DDrot(DDName(rotNameNippleToBody, "pixfwdNipple"),
302  std::make_unique<DDRotationMatrix>( rpNB.xx(), rpNB.xy(), rpNB.xz(),
303  rpNB.yx(), rpNB.yy(), rpNB.yz(),
304  rpNB.zx(), rpNB.zy(), rpNB.zz()));
305  double angleBody = vZ.angle(rpNB * vZ);
306  LogDebug("PixelGeom") << " Angle to body : " << angleBody;
307 }
308 
309 // ---------------------------------------------------------------------------------------
310 
#define LogDebug(id)
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:80
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:68
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
DDRotation DDrot(const DDName &name, std::unique_ptr< DDRotationMatrix > rot)
Definition of a uniquely identifiable rotation matrix named by DDName name.
Definition: DDRotation.cc:80
CLHEP::HepRotation * nippleRotationZPlus
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
const DDRotationMatrix & rotation() const
Returns the read-only rotation-matrix.
Definition: DDTransform.h:93
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:18
std::string flagSelector
std::string childRotationName
const std::string & name() const
Returns the name.
Definition: DDName.cc:53
void initialize(const DDNumericArguments &nArgs, const DDVectorArguments &vArgs, const DDMapArguments &mArgs, const DDStringArguments &sArgs, const DDStringVectorArguments &vsArgs) override