CMS 3D CMS Logo

DDPixFwdBlades.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/GlobalSystemOfUnits.h"
23 
24 #include <cmath>
25 #include <algorithm>
26 #include <map>
27 #include <string>
28 #include <vector>
29 
30 /*
31 
32 == CMS Forward Pixels Geometry ==
33 
34  @version 3.02.01 May 30, 2006
35  @created Dmitry Onoprienko
36 
37 == ALGORITHM DESCRIPTION: ==
38 
39  Algorithm for placing one-per-blade components
40  Also computes parameters necessary for defining the "nipple" geometry.
41 
42 == Parameters : ==
43 
44  "Endcap" - +1 if placing the child volume into +Z disk, -1 if placing into -Z disk.
45  "Child" - name of a child volume being places (should be in the form "file:volume")
46  In no child name is given, the algorithm simply calculates Nipple parameters.
47  "ChildRotation" - rotation of the child volume with respect to the "blade frame". [OPTIONAL]
48  "ChildTranslation" - vector defining translation of the child volume with respect to the
49  "blade frame". [OPTIONAL]
50  "FlagString" - string of 24 characters, used to indicate blades into which the child volume
51  should be placed. [OPTIONAL]
52  "FlagSelector" - 1 character string, key to interpreting "FlagString".
53  Positions in "BladeFlag" that have this character will get the child volume.
54 
55  If "Child" parameter is omitted, the algorithm computes rotation needed for describing
56  coolant "nipples" but does not do any placements.
57 
58  If "Child" is "PixelForwardNippleZPlus" or "PixelForwardNippleZMinus" and no rotation or translation
59  is supplied, correct rotations and translations are automatically computed.
60 
61  Blade frame: origin on the axis of the blade at a distance "ancorRadius" from the beam line
62  (it therefore coincides with the ancor point of a blade).
63  Y along blade axis pointing away from beam line, Z perpendicular to blade plane and pointing away from IP.
64  (That assumes the axes of ZPlus disk are aligned with CMS global reference frame, and ZMinus disk
65  is rotated around Y by 180 degrees.)
66 
67 == Example of use : ==
68 
69 <Algorithm name="track:DDPixFwdBlades">
70  <rParent name="pixfwdDisk:PixelForwardDiskZMinus"/>
71  <Numeric name="Endcap" value="-1." />
72  <String name="Child" value="pixfwdPanel:PixelForwardPanel4Left"/>
73  <Vector name="ChildTranslation" type="numeric" nEntries="3"> 0., -[pixfwdPanel:AncorY], [zPanel] </Vector>
74  <String name="ChildRotation" value="pixfwdCommon:Y180"/>
75  <String name="FlagString" value="LRRRRLRRRRRRLRRRRLRRRRRR" /> <!-- Panel Layout ZMinus 4 -->
76  <String name="FlagSelector" value="L" />
77 </Algorithm>
78 
79 */
80 
81 using namespace std;
82 
83 class DDPixFwdBlades : public DDAlgorithm {
84 public:
86  ~DDPixFwdBlades() override;
87 
88  void initialize(const DDNumericArguments& nArgs,
89  const DDVectorArguments& vArgs,
90  const DDMapArguments& mArgs,
91  const DDStringArguments& sArgs,
92  const DDStringVectorArguments& vsArgs) override;
93 
94  void execute(DDCompactView& cpv) override;
95 
96 private:
97  int nBlades; // Number of blades
98  double bladeAngle; // Angle of blade rotation around axis perpendicular to beam
99  double zPlane; // Common shift in Z for all blades (with respect to disk center plane)
100  double bladeZShift; // Shift in Z between the axes of two adjacent blades
101 
102  double ancorRadius; // Distance from beam line to ancor point defining center of "blade frame"
103 
104  // Coordinates of Nipple ancor points J and K in "blade frame" :
105 
106  double jX;
107  double jY;
108  double jZ;
109  double kX;
110  double kY;
111  double kZ;
112 
113  double endcap; // +1 for Z Plus endcap disks, -1 for Z Minus endcap disks
114 
115  string flagString; // String of flags
116  string flagSelector; // Character that means "yes" in flagString
117 
118  string childName; // Child volume name
119 
120  vector<double> childTranslationVector; // Child translation with respect to "blade frame"
121  string childRotationName; // Child rotation with respect to "blade frame"
122  string idNameSpace; //Namespace of this and ALL sub-parts
123 
124  map<string, int> copyNumbers;
125 
126  CLHEP::HepRotation* nippleRotationZPlus;
127  CLHEP::HepRotation* nippleRotationZMinus;
128  double nippleTranslationX, nippleTranslationY, nippleTranslationZ;
129 
130  int issueCopyNumber();
131  void computeNippleParameters(double endcap);
132 };
133 
136 
138  const DDVectorArguments& vArgs,
139  const DDMapArguments&,
140  const DDStringArguments& sArgs,
141  const DDStringVectorArguments&) {
142  if (nArgs.find("Endcap") != nArgs.end()) {
143  endcap = nArgs["Endcap"];
144  } else {
145  endcap = 1.;
146  }
147 
148  if (sArgs.find("FlagString") != sArgs.end()) {
149  flagString = sArgs["FlagString"];
150  flagSelector = sArgs["FlagSelector"];
151  } else {
152  flagString = "YYYYYYYYYYYYYYYYYYYYYYYY";
153  flagSelector = "Y";
154  }
155 
156  if (sArgs.find("Child") != sArgs.end()) {
157  childName = sArgs["Child"];
158  } else {
159  childName = "";
160  }
161 
162  if (vArgs.find("ChildTranslation") != vArgs.end()) {
163  childTranslationVector = vArgs["ChildTranslation"];
164  } else {
165  childTranslationVector = vector<double>(3, 0.);
166  }
167 
168  if (sArgs.find("ChildRotation") != sArgs.end()) {
169  childRotationName = sArgs["ChildRotation"];
170  } else {
171  childRotationName = "";
172  }
173 
174  idNameSpace = DDCurrentNamespace::ns();
175 
176  // -- Input geometry parameters : -----------------------------------------------------
177 
178  nBlades = 24; // Number of blades
179  bladeAngle = 20. * CLHEP::deg; // Angle of blade rotation around its axis
180  zPlane = 0.; // Common shift in Z for all blades (with respect to disk center plane)
181  bladeZShift = 6. * CLHEP::mm; // Shift in Z between the axes of two adjacent blades
182 
183  ancorRadius = 54.631 * CLHEP::mm; // Distance from beam line to ancor point defining center of "blade frame"
184 
185  // Coordinates of Nipple ancor points J and K in "blade frame" :
186 
187  jX = -16.25 * CLHEP::mm;
188  jY = 96.50 * CLHEP::mm;
189  jZ = 1.25 * CLHEP::mm;
190  kX = 16.25 * CLHEP::mm;
191  kY = 96.50 * CLHEP::mm;
192  kZ = -1.25 * CLHEP::mm;
193 
194  // -- Static initialization : -----------------------------------------------------------
195 
196  nippleRotationZPlus = nullptr;
197  nippleRotationZMinus = nullptr;
198  nippleTranslationX = 0.;
199  nippleTranslationY = 0.;
200  nippleTranslationZ = 0.;
201 
202  copyNumbers.clear();
203 }
204 
206  // -- Compute Nipple parameters if not already computed :
207 
208  if (!nippleRotationZPlus) {
209  computeNippleParameters(1.); // Z Plus endcap
210  computeNippleParameters(-1.); // Z Minus endcap
211  }
212  if (childName.empty())
213  return;
214 
215  // -- Signed versions of blade angle and z-shift :
216 
217  double effBladeAngle = -endcap * bladeAngle;
218  double effBladeZShift = endcap * bladeZShift;
219 
220  // -- Names of mother and child volumes :
221 
222  DDName mother = parent().name();
223  DDName child(DDSplit(childName).first, DDSplit(childName).second);
224 
225  // -- Get translation and rotation from "blade frame" to "child frame", if any :
226 
227  CLHEP::HepRotation childRotMatrix = CLHEP::HepRotation();
228  if (!childRotationName.empty()) {
229  DDRotation childRotation = DDRotation(DDName(DDSplit(childRotationName).first, DDSplit(childRotationName).second));
230  // due to conversion to ROOT::Math::Rotation3D -- Michael Case
231  DD3Vector x, y, z;
232  childRotation.rotation().GetComponents(x, y, z); // these are the orthonormal columns.
233  CLHEP::HepRep3x3 tr(x.X(), y.X(), z.X(), x.Y(), y.Y(), z.Y(), x.Z(), y.Z(), z.Z());
234  childRotMatrix = CLHEP::HepRotation(tr);
235  } else if (childName == "pixfwdNipple:PixelForwardNippleZPlus") {
236  childRotMatrix = *nippleRotationZPlus;
237  } else if (childName == "pixfwdNipple:PixelForwardNippleZMinus") {
238  childRotMatrix = *nippleRotationZMinus;
239  }
240 
241  CLHEP::Hep3Vector childTranslation;
242  if (childName == "pixfwdNipple:PixelForwardNippleZPlus") {
243  childTranslation = CLHEP::Hep3Vector(nippleTranslationX, nippleTranslationY, nippleTranslationZ);
244  } else if (childName == "pixfwdNipple:PixelForwardNippleZMinus") {
245  childTranslation = CLHEP::Hep3Vector(-nippleTranslationX, nippleTranslationY, nippleTranslationZ);
246  } else {
247  childTranslation =
248  CLHEP::Hep3Vector(childTranslationVector[0], childTranslationVector[1], childTranslationVector[2]);
249  }
250 
251  // Create a matrix for rotation around blade axis (to "blade frame") :
252 
253  CLHEP::HepRotation bladeRotMatrix(CLHEP::Hep3Vector(0., 1., 0.), effBladeAngle);
254 
255  // Cycle over Phi positions, placing copies of the child volume :
256 
257  double deltaPhi = (360. / nBlades) * CLHEP::deg;
258  int nQuarter = nBlades / 4;
259  double zShiftMax = effBladeZShift * ((nQuarter - 1) / 2.);
260 
261  for (int iBlade = 0; iBlade < nBlades; iBlade++) {
262  // check if this blade position should be skipped :
263 
264  if (flagString[iBlade] != flagSelector[0])
265  continue;
266  int copy = issueCopyNumber();
267 
268  // calculate Phi and Z shift for this blade :
269 
270  double phi = (iBlade + 0.5) * deltaPhi - 90. * CLHEP::deg;
271  int iQuarter = iBlade % nQuarter;
272  double zShift = -zShiftMax + iQuarter * effBladeZShift;
273 
274  // compute rotation matrix from mother to blade frame :
275 
276  CLHEP::HepRotation rotMatrix(CLHEP::Hep3Vector(0., 0., 1.), phi);
277  rotMatrix *= bladeRotMatrix;
278 
279  // convert translation vector from blade frame to mother frame, and add Z shift :
280 
281  CLHEP::Hep3Vector translation = rotMatrix(childTranslation + CLHEP::Hep3Vector(0., ancorRadius, 0.));
282  translation += CLHEP::Hep3Vector(0., 0., zShift + zPlane);
283 
284  // create DDRotation for placing the child if not already existent :
285 
287  string rotstr = mother.name() + DDSplit(childName).first + to_string(copy);
288  rotation = DDRotation(DDName(rotstr, idNameSpace));
289 
290  if (!rotation) {
291  rotMatrix *= childRotMatrix;
292  rotation = DDrot(DDName(rotstr, idNameSpace),
293  make_unique<DDRotationMatrix>(rotMatrix.xx(),
294  rotMatrix.xy(),
295  rotMatrix.xz(),
296  rotMatrix.yx(),
297  rotMatrix.yy(),
298  rotMatrix.yz(),
299  rotMatrix.zx(),
300  rotMatrix.zy(),
301  rotMatrix.zz()));
302  }
303  // position the child :
304 
305  DDTranslation ddtran(translation.x(), translation.y(), translation.z());
306  cpv.position(child, mother, copy, ddtran, rotation);
307  }
308 
309  // End of cycle over Phi positions
310 }
311 
313  if (copyNumbers.count(childName) == 0)
314  copyNumbers[childName] = 0;
315  return ++copyNumbers[childName];
316 }
317 
318 // -- Calculating Nipple parameters : ---------------------------------------------------
319 
321  double effBladeAngle = endcap * bladeAngle;
322 
323  CLHEP::Hep3Vector jC; // Point J in the "cover" blade frame
324  CLHEP::Hep3Vector kB; // Point K in the "body" blade frame
325  string rotNameNippleToCover;
326  string rotNameCoverToNipple;
327  string rotNameNippleToBody;
328 
329  if (endcap > 0.) {
330  jC = CLHEP::Hep3Vector(jX, jY + ancorRadius, jZ);
331  kB = CLHEP::Hep3Vector(kX, kY + ancorRadius, kZ);
332  rotNameNippleToCover = "NippleToCoverZPlus";
333  rotNameCoverToNipple = "CoverToNippleZPlus";
334  rotNameNippleToBody = "NippleToBodyZPlus";
335  } else {
336  jC = CLHEP::Hep3Vector(-jX, jY + ancorRadius, jZ);
337  kB = CLHEP::Hep3Vector(-kX, kY + ancorRadius, kZ);
338  rotNameNippleToCover = "NippleToCoverZMinus";
339  rotNameCoverToNipple = "CoverToNippleZMinus";
340  rotNameNippleToBody = "NippleToBodyZMinus";
341  }
342 
343  // Z-shift from "cover" to "body" blade frame:
344 
345  CLHEP::Hep3Vector tCB(bladeZShift * sin(effBladeAngle), 0., bladeZShift * cos(effBladeAngle));
346 
347  // Rotation from "cover" blade frame into "body" blade frame :
348 
349  double deltaPhi = endcap * (360. / nBlades) * CLHEP::deg;
350  CLHEP::HepRotation rCB(CLHEP::Hep3Vector(1. * sin(effBladeAngle), 0., 1. * cos(effBladeAngle)), deltaPhi);
351 
352  // Transform vector k into "cover" blade frame :
353 
354  CLHEP::Hep3Vector kC = rCB * (kB + tCB);
355 
356  // Vector JK in the "cover" blade frame:
357 
358  CLHEP::Hep3Vector jkC = kC - jC;
359  double jkLength = jkC.mag();
360  DDConstant JK(DDName("JK", "pixfwdNipple"), make_unique<double>(jkLength));
361  LogDebug("PixelGeom") << "+++++++++++++++ DDPixFwdBlades: "
362  << "JK Length " << jkLength * CLHEP::mm;
363 
364  // Position of the center of a nipple in "cover" blade frame :
365 
366  CLHEP::Hep3Vector nippleTranslation((kC + jC) / 2. - CLHEP::Hep3Vector(0., ancorRadius, 0.));
367  if (endcap > 0) {
368  nippleTranslationX = nippleTranslation.x();
369  nippleTranslationY = nippleTranslation.y();
370  nippleTranslationZ = nippleTranslation.z();
371  }
372  LogDebug("PixelGeom") << "Child translation : " << nippleTranslation;
373 
374  // Rotations from nipple frame to "cover" blade frame and back :
375 
376  CLHEP::Hep3Vector vZ(0., 0., 1.);
377  CLHEP::Hep3Vector axis = vZ.cross(jkC);
378  double angleCover = vZ.angle(jkC);
379  LogDebug("PixelGeom") << " Angle to Cover: " << angleCover;
380  CLHEP::HepRotation* rpCN = new CLHEP::HepRotation(axis, angleCover);
381  if (endcap > 0.) {
382  nippleRotationZPlus = rpCN;
383  } else {
384  nippleRotationZMinus = rpCN;
385  }
386  //( endcap > 0. ? nippleRotationZPlus : nippleRotationZMinus ) = rpCN;
387 
388  DDrot(
389  DDName(rotNameCoverToNipple, "pixfwdNipple"),
390  make_unique<DDRotationMatrix>(
391  rpCN->xx(), rpCN->xy(), rpCN->xz(), rpCN->yx(), rpCN->yy(), rpCN->yz(), rpCN->zx(), rpCN->zy(), rpCN->zz()));
392  CLHEP::HepRotation rpNC(axis, -angleCover);
393 
394  DDrot(DDName(rotNameNippleToCover, "pixfwdNipple"),
395  make_unique<DDRotationMatrix>(
396  rpNC.xx(), rpNC.xy(), rpNC.xz(), rpNC.yx(), rpNC.yy(), rpNC.yz(), rpNC.zx(), rpNC.zy(), rpNC.zz()));
397 
398  // Rotation from nipple frame to "body" blade frame :
399 
400  CLHEP::HepRotation rpNB(rpNC * rCB);
401 
402  DDrot(DDName(rotNameNippleToBody, "pixfwdNipple"),
403  make_unique<DDRotationMatrix>(
404  rpNB.xx(), rpNB.xy(), rpNB.xz(), rpNB.yx(), rpNB.yy(), rpNB.yz(), rpNB.zx(), rpNB.zy(), rpNB.zz()));
405  double angleBody = vZ.angle(rpNB * vZ);
406  LogDebug("PixelGeom") << " Angle to body : " << angleBody;
407 }
408 
409 DEFINE_EDM_PLUGIN(DDAlgorithmFactory, DDPixFwdBlades, "track:DDPixFwdBlades");
DDPixFwdBlades::nBlades
int nBlades
Definition: DDPixFwdBlades.cc:97
DDCurrentNamespace.h
DDPixFwdBlades::childRotationName
string childRotationName
Definition: DDPixFwdBlades.cc:121
DDTransform.h
MessageLogger.h
DDrot
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
filterCSVwithJSON.copy
copy
Definition: filterCSVwithJSON.py:36
DDName
DDName is used to identify DDD entities uniquely.
Definition: DDName.h:15
DDPixFwdBlades::endcap
double endcap
Definition: DDPixFwdBlades.cc:113
DDSplit.h
DDPixFwdBlades::computeNippleParameters
void computeNippleParameters(double endcap)
Definition: DDPixFwdBlades.cc:320
edm::second
U second(std::pair< T, U > const &p)
Definition: ParameterSet.cc:222
DDPixFwdBlades
Definition: DDPixFwdBlades.cc:83
DDPixFwdBlades::nippleTranslationZ
double nippleTranslationZ
Definition: DDPixFwdBlades.cc:128
makeMuonMisalignmentScenario.endcap
endcap
Definition: makeMuonMisalignmentScenario.py:320
DDPixFwdBlades::initialize
void initialize(const DDNumericArguments &nArgs, const DDVectorArguments &vArgs, const DDMapArguments &mArgs, const DDStringArguments &sArgs, const DDStringVectorArguments &vsArgs) override
Definition: DDPixFwdBlades.cc:137
funct::sin
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
DDPixFwdBlades::execute
void execute(DDCompactView &cpv) override
Definition: DDPixFwdBlades.cc:205
funct::cos
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
DDTranslation
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double > > DDTranslation
Definition: DDTranslation.h:7
SiPixelRawToDigiRegional_cfi.deltaPhi
deltaPhi
Definition: SiPixelRawToDigiRegional_cfi.py:9
DDPixFwdBlades::DDPixFwdBlades
DDPixFwdBlades()
Definition: DDPixFwdBlades.cc:134
DDCompactView
Compact representation of the geometrical detector hierarchy.
Definition: DDCompactView.h:81
DDSolid.h
DEFINE_EDM_PLUGIN
#define DEFINE_EDM_PLUGIN(factory, type, name)
Definition: PluginFactory.h:124
DDPixFwdBlades::issueCopyNumber
int issueCopyNumber()
Definition: DDPixFwdBlades.cc:312
first
auto first
Definition: CAHitNtupletGeneratorKernelsImpl.h:112
DD3Vector
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double > > DD3Vector
Definition: PGeometricDetBuilder.cc:19
DDPixFwdBlades::zPlane
double zPlane
Definition: DDPixFwdBlades.cc:99
LogDebug
#define LogDebug(id)
Definition: MessageLogger.h:233
idealTransformation.rotation
dictionary rotation
Definition: idealTransformation.py:1
edmplugin::PluginFactory
Definition: PluginFactory.h:34
DDPixFwdBlades::bladeAngle
double bladeAngle
Definition: DDPixFwdBlades.cc:98
DDTypes.h
DDPixFwdBlades::nippleRotationZPlus
CLHEP::HepRotation * nippleRotationZPlus
Definition: DDPixFwdBlades.cc:126
DDMaterial.h
DDRotation::rotation
const DDRotationMatrix & rotation() const
Returns the read-only rotation-matrix.
Definition: DDTransform.h:81
DDName::name
const std::string & name() const
Returns the name.
Definition: DDName.cc:41
DDLogicalPart.h
DDPixFwdBlades::flagSelector
string flagSelector
Definition: DDPixFwdBlades.cc:116
DDPixFwdBlades::bladeZShift
double bladeZShift
Definition: DDPixFwdBlades.cc:100
DDPixFwdBlades::idNameSpace
string idNameSpace
Definition: DDPixFwdBlades.cc:122
DDPixFwdBlades::kZ
double kZ
Definition: DDPixFwdBlades.cc:111
ReadMapType< double >
DDAlgorithm.h
std
Definition: JetResolutionObject.h:76
DDConstant
a named constant corresponding to the DDL-XML tag <Constant> and <ConstantsVector>
Definition: DDConstant.h:18
submitPVValidationJobs.child
child
Definition: submitPVValidationJobs.py:119
DDRotationMatrix.h
DDCurrentNamespace::ns
static std::string & ns()
Definition: DDCurrentNamespace.cc:3
DDPixFwdBlades::~DDPixFwdBlades
~DDPixFwdBlades() override
Definition: DDPixFwdBlades.cc:135
DDPixFwdBlades::flagString
string flagString
Definition: DDPixFwdBlades.cc:115
DDPixFwdBlades::kX
double kX
Definition: DDPixFwdBlades.cc:109
DDPixFwdBlades::jY
double jY
Definition: DDPixFwdBlades.cc:107
DDPixFwdBlades::nippleRotationZMinus
CLHEP::HepRotation * nippleRotationZMinus
Definition: DDPixFwdBlades.cc:127
DDRotation
Represents a uniquely identifyable rotation matrix.
Definition: DDTransform.h:57
DDPixFwdBlades::copyNumbers
map< string, int > copyNumbers
Definition: DDPixFwdBlades.cc:124
initialize
static AlgebraicMatrix initialize()
Definition: BeamSpotTransientTrackingRecHit.cc:24
DDPixFwdBlades::kY
double kY
Definition: DDPixFwdBlades.cc:110
DDPixFwdBlades::jX
double jX
Definition: DDPixFwdBlades.cc:106
child
Definition: simpleInheritance.h:11
DDPixFwdBlades::ancorRadius
double ancorRadius
Definition: DDPixFwdBlades.cc:102
DDAlgorithmFactory.h
DDConstant.h
class-composition.parent
parent
Definition: class-composition.py:88
DDPixFwdBlades::jZ
double jZ
Definition: DDPixFwdBlades.cc:108
DDSplit
std::pair< std::string, std::string > DDSplit(const std::string &n)
split into (name,namespace), separator = ':'
Definition: DDSplit.cc:3
DDCompactView::position
void position(const DDLogicalPart &self, const DDLogicalPart &parent, const std::string &copyno, const DDTranslation &trans, const DDRotation &rot, const DDDivision *div=nullptr)
Definition: DDCompactView.cc:76
DDRotation
ROOT::Math::Rotation3D DDRotation
Definition: DDEcalEndcapAlgo.cc:16
DDPixFwdBlades::childTranslationVector
vector< double > childTranslationVector
Definition: DDPixFwdBlades.cc:120
DDPixFwdBlades::childName
string childName
Definition: DDPixFwdBlades.cc:118