File indexing completed on 2024-05-10 02:20:53
0001
0002
0003
0004
0005
0006 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0007 #include "DetectorDescription/Core/interface/DDRotationMatrix.h"
0008 #include "DetectorDescription/Core/interface/DDLogicalPart.h"
0009 #include "DetectorDescription/Core/interface/DDSolid.h"
0010 #include "DetectorDescription/Core/interface/DDMaterial.h"
0011 #include "DetectorDescription/Core/interface/DDCurrentNamespace.h"
0012 #include "DetectorDescription/Core/interface/DDSplit.h"
0013 #include "DetectorDescription/Core/interface/DDConstant.h"
0014 #include "DetectorDescription/Core/interface/DDTypes.h"
0015 #include "DetectorDescription/Core/interface/DDAlgorithm.h"
0016 #include "DetectorDescription/Core/interface/DDAlgorithmFactory.h"
0017 #include "DetectorDescription/Core/interface/DDTransform.h"
0018 #include <CLHEP/Vector/ThreeVector.h>
0019 #include <CLHEP/Vector/Rotation.h>
0020 #include <CLHEP/Vector/RotationInterfaces.h>
0021 #include <CLHEP/Units/GlobalPhysicalConstants.h>
0022 #include <CLHEP/Units/SystemOfUnits.h>
0023
0024 #include <cmath>
0025 #include <algorithm>
0026 #include <map>
0027 #include <string>
0028 #include <vector>
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081 using namespace std;
0082
0083 class DDPixFwdBlades : public DDAlgorithm {
0084 public:
0085 DDPixFwdBlades();
0086 ~DDPixFwdBlades() override;
0087
0088 void initialize(const DDNumericArguments& nArgs,
0089 const DDVectorArguments& vArgs,
0090 const DDMapArguments& mArgs,
0091 const DDStringArguments& sArgs,
0092 const DDStringVectorArguments& vsArgs) override;
0093
0094 void execute(DDCompactView& cpv) override;
0095
0096 private:
0097 int nBlades;
0098 double bladeAngle;
0099 double zPlane;
0100 double bladeZShift;
0101
0102 double ancorRadius;
0103
0104
0105
0106 double jX;
0107 double jY;
0108 double jZ;
0109 double kX;
0110 double kY;
0111 double kZ;
0112
0113 double endcap;
0114
0115 string flagString;
0116 string flagSelector;
0117
0118 string childName;
0119
0120 vector<double> childTranslationVector;
0121 string childRotationName;
0122 string idNameSpace;
0123
0124 map<string, int> copyNumbers;
0125
0126 CLHEP::HepRotation* nippleRotationZPlus;
0127 CLHEP::HepRotation* nippleRotationZMinus;
0128 double nippleTranslationX, nippleTranslationY, nippleTranslationZ;
0129
0130 int issueCopyNumber();
0131 void computeNippleParameters(double endcap);
0132 };
0133
0134 DDPixFwdBlades::DDPixFwdBlades() {}
0135 DDPixFwdBlades::~DDPixFwdBlades() {}
0136
0137 void DDPixFwdBlades::initialize(const DDNumericArguments& nArgs,
0138 const DDVectorArguments& vArgs,
0139 const DDMapArguments&,
0140 const DDStringArguments& sArgs,
0141 const DDStringVectorArguments&) {
0142 if (nArgs.find("Endcap") != nArgs.end()) {
0143 endcap = nArgs["Endcap"];
0144 } else {
0145 endcap = 1.;
0146 }
0147
0148 if (sArgs.find("FlagString") != sArgs.end()) {
0149 flagString = sArgs["FlagString"];
0150 flagSelector = sArgs["FlagSelector"];
0151 } else {
0152 flagString = "YYYYYYYYYYYYYYYYYYYYYYYY";
0153 flagSelector = "Y";
0154 }
0155
0156 if (sArgs.find("Child") != sArgs.end()) {
0157 childName = sArgs["Child"];
0158 } else {
0159 childName = "";
0160 }
0161
0162 if (vArgs.find("ChildTranslation") != vArgs.end()) {
0163 childTranslationVector = vArgs["ChildTranslation"];
0164 } else {
0165 childTranslationVector = vector<double>(3, 0.);
0166 }
0167
0168 if (sArgs.find("ChildRotation") != sArgs.end()) {
0169 childRotationName = sArgs["ChildRotation"];
0170 } else {
0171 childRotationName = "";
0172 }
0173
0174 idNameSpace = DDCurrentNamespace::ns();
0175
0176
0177
0178 nBlades = 24;
0179 bladeAngle = 20. * CLHEP::deg;
0180 zPlane = 0.;
0181 bladeZShift = 6. * CLHEP::mm;
0182
0183 ancorRadius = 54.631 * CLHEP::mm;
0184
0185
0186
0187 jX = -16.25 * CLHEP::mm;
0188 jY = 96.50 * CLHEP::mm;
0189 jZ = 1.25 * CLHEP::mm;
0190 kX = 16.25 * CLHEP::mm;
0191 kY = 96.50 * CLHEP::mm;
0192 kZ = -1.25 * CLHEP::mm;
0193
0194
0195
0196 nippleRotationZPlus = nullptr;
0197 nippleRotationZMinus = nullptr;
0198 nippleTranslationX = 0.;
0199 nippleTranslationY = 0.;
0200 nippleTranslationZ = 0.;
0201
0202 copyNumbers.clear();
0203
0204 edm::LogVerbatim("PixelGeom") << "DDPixFwdBlades: Initialize with endcap " << endcap << " FlagString " << flagString
0205 << " FlagSelector " << flagSelector << " Child " << childName << " ChildTranslation "
0206 << childTranslationVector[0] << ":" << childTranslationVector[1] << ":"
0207 << childTranslationVector[2] << " ChildRotation " << childRotationName << " NameSpace "
0208 << idNameSpace << "\n nBlades " << nBlades << " bladeAngle " << bladeAngle
0209 << " zPlane " << zPlane << " bladeZShift " << bladeZShift << " ancorRadius "
0210 << ancorRadius << " jX|jY|jZ " << jX << ":" << jY << ":" << jZ << " kX|kY|kZ " << kX
0211 << ":" << kY << ":" << kZ;
0212 }
0213
0214 void DDPixFwdBlades::execute(DDCompactView& cpv) {
0215
0216
0217 if (!nippleRotationZPlus) {
0218 computeNippleParameters(1.);
0219 computeNippleParameters(-1.);
0220 }
0221 if (childName.empty())
0222 return;
0223
0224
0225
0226 double effBladeAngle = -endcap * bladeAngle;
0227 double effBladeZShift = endcap * bladeZShift;
0228
0229
0230
0231 DDName mother = parent().name();
0232 DDName child(DDSplit(childName).first, DDSplit(childName).second);
0233
0234
0235
0236 CLHEP::HepRotation childRotMatrix = CLHEP::HepRotation();
0237 if (!childRotationName.empty()) {
0238 DDRotation childRotation = DDRotation(DDName(DDSplit(childRotationName).first, DDSplit(childRotationName).second));
0239
0240 DD3Vector x, y, z;
0241 childRotation.rotation().GetComponents(x, y, z);
0242 CLHEP::HepRep3x3 tr(x.X(), y.X(), z.X(), x.Y(), y.Y(), z.Y(), x.Z(), y.Z(), z.Z());
0243 childRotMatrix = CLHEP::HepRotation(tr);
0244 } else if (childName == "pixfwdNipple:PixelForwardNippleZPlus") {
0245 childRotMatrix = *nippleRotationZPlus;
0246 } else if (childName == "pixfwdNipple:PixelForwardNippleZMinus") {
0247 childRotMatrix = *nippleRotationZMinus;
0248 }
0249
0250 CLHEP::Hep3Vector childTranslation;
0251 if (childName == "pixfwdNipple:PixelForwardNippleZPlus") {
0252 childTranslation = CLHEP::Hep3Vector(nippleTranslationX, nippleTranslationY, nippleTranslationZ);
0253 } else if (childName == "pixfwdNipple:PixelForwardNippleZMinus") {
0254 childTranslation = CLHEP::Hep3Vector(-nippleTranslationX, nippleTranslationY, nippleTranslationZ);
0255 } else {
0256 childTranslation =
0257 CLHEP::Hep3Vector(childTranslationVector[0], childTranslationVector[1], childTranslationVector[2]);
0258 }
0259
0260
0261
0262 CLHEP::HepRotation bladeRotMatrix(CLHEP::Hep3Vector(0., 1., 0.), effBladeAngle);
0263
0264
0265
0266 double deltaPhi = (360. / nBlades) * CLHEP::deg;
0267 int nQuarter = nBlades / 4;
0268 double zShiftMax = effBladeZShift * ((nQuarter - 1) / 2.);
0269
0270 for (int iBlade = 0; iBlade < nBlades; iBlade++) {
0271
0272
0273 if (flagString[iBlade] != flagSelector[0])
0274 continue;
0275 int copy = issueCopyNumber();
0276
0277
0278
0279 double phi = (iBlade + 0.5) * deltaPhi - 90. * CLHEP::deg;
0280 int iQuarter = iBlade % nQuarter;
0281 double zShift = -zShiftMax + iQuarter * effBladeZShift;
0282
0283
0284
0285 CLHEP::HepRotation rotMatrix(CLHEP::Hep3Vector(0., 0., 1.), phi);
0286 rotMatrix *= bladeRotMatrix;
0287
0288
0289
0290 CLHEP::Hep3Vector translation = rotMatrix(childTranslation + CLHEP::Hep3Vector(0., ancorRadius, 0.));
0291 translation += CLHEP::Hep3Vector(0., 0., zShift + zPlane);
0292
0293
0294
0295 DDRotation rotation;
0296 string rotstr = mother.name() + DDSplit(childName).first + to_string(copy);
0297 rotation = DDRotation(DDName(rotstr, idNameSpace));
0298 edm::LogVerbatim("PixelGeom") << "DDPixFwdBlades: Rotation " << rotstr << " : " << rotation;
0299
0300 if (!rotation) {
0301 rotMatrix *= childRotMatrix;
0302 rotation = DDrot(DDName(rotstr, idNameSpace),
0303 make_unique<DDRotationMatrix>(rotMatrix.xx(),
0304 rotMatrix.xy(),
0305 rotMatrix.xz(),
0306 rotMatrix.yx(),
0307 rotMatrix.yy(),
0308 rotMatrix.yz(),
0309 rotMatrix.zx(),
0310 rotMatrix.zy(),
0311 rotMatrix.zz()));
0312 }
0313
0314
0315 DDTranslation ddtran(translation.x(), translation.y(), translation.z());
0316 cpv.position(child, mother, copy, ddtran, rotation);
0317 edm::LogVerbatim("PixelGeom") << "DDPixFwdBlades::Position " << child << " copy " << copy << " in " << mother
0318 << " with translation " << ddtran << " and rotation " << rotation;
0319 }
0320
0321
0322 }
0323
0324 int DDPixFwdBlades::issueCopyNumber() {
0325 if (copyNumbers.count(childName) == 0)
0326 copyNumbers[childName] = 0;
0327 return ++copyNumbers[childName];
0328 }
0329
0330
0331
0332 void DDPixFwdBlades::computeNippleParameters(double endcap) {
0333 double effBladeAngle = endcap * bladeAngle;
0334
0335 CLHEP::Hep3Vector jC;
0336 CLHEP::Hep3Vector kB;
0337 string rotNameNippleToCover;
0338 string rotNameCoverToNipple;
0339 string rotNameNippleToBody;
0340
0341 if (endcap > 0.) {
0342 jC = CLHEP::Hep3Vector(jX, jY + ancorRadius, jZ);
0343 kB = CLHEP::Hep3Vector(kX, kY + ancorRadius, kZ);
0344 rotNameNippleToCover = "NippleToCoverZPlus";
0345 rotNameCoverToNipple = "CoverToNippleZPlus";
0346 rotNameNippleToBody = "NippleToBodyZPlus";
0347 } else {
0348 jC = CLHEP::Hep3Vector(-jX, jY + ancorRadius, jZ);
0349 kB = CLHEP::Hep3Vector(-kX, kY + ancorRadius, kZ);
0350 rotNameNippleToCover = "NippleToCoverZMinus";
0351 rotNameCoverToNipple = "CoverToNippleZMinus";
0352 rotNameNippleToBody = "NippleToBodyZMinus";
0353 }
0354
0355
0356
0357 CLHEP::Hep3Vector tCB(bladeZShift * sin(effBladeAngle), 0., bladeZShift * cos(effBladeAngle));
0358
0359
0360
0361 double deltaPhi = endcap * (360. / nBlades) * CLHEP::deg;
0362 CLHEP::HepRotation rCB(CLHEP::Hep3Vector(1. * sin(effBladeAngle), 0., 1. * cos(effBladeAngle)), deltaPhi);
0363
0364
0365
0366 CLHEP::Hep3Vector kC = rCB * (kB + tCB);
0367
0368
0369
0370 CLHEP::Hep3Vector jkC = kC - jC;
0371 double jkLength = jkC.mag();
0372 DDConstant JK(DDName("JK", "pixfwdNipple"), make_unique<double>(jkLength));
0373 edm::LogVerbatim("PixelGeom") << "+++++++++++++++ DDPixFwdBlades: "
0374 << "JK Length " << jkLength * CLHEP::mm;
0375
0376
0377
0378 CLHEP::Hep3Vector nippleTranslation((kC + jC) / 2. - CLHEP::Hep3Vector(0., ancorRadius, 0.));
0379 if (endcap > 0) {
0380 nippleTranslationX = nippleTranslation.x();
0381 nippleTranslationY = nippleTranslation.y();
0382 nippleTranslationZ = nippleTranslation.z();
0383 }
0384 edm::LogVerbatim("PixelGeom") << "Child translation : " << nippleTranslation;
0385
0386
0387
0388 CLHEP::Hep3Vector vZ(0., 0., 1.);
0389 CLHEP::Hep3Vector axis = vZ.cross(jkC);
0390 double angleCover = vZ.angle(jkC);
0391 edm::LogVerbatim("PixelGeom") << " Angle to Cover: " << angleCover;
0392 CLHEP::HepRotation* rpCN = new CLHEP::HepRotation(axis, angleCover);
0393 if (endcap > 0.) {
0394 nippleRotationZPlus = rpCN;
0395 } else {
0396 nippleRotationZMinus = rpCN;
0397 }
0398
0399
0400 DDrot(
0401 DDName(rotNameCoverToNipple, "pixfwdNipple"),
0402 make_unique<DDRotationMatrix>(
0403 rpCN->xx(), rpCN->xy(), rpCN->xz(), rpCN->yx(), rpCN->yy(), rpCN->yz(), rpCN->zx(), rpCN->zy(), rpCN->zz()));
0404 CLHEP::HepRotation rpNC(axis, -angleCover);
0405 edm::LogVerbatim("PixelGeom") << "DDPixFwdBlades::Defines " << DDName(rotNameCoverToNipple, "pixfwdNipple")
0406 << " with " << rpCN;
0407 DDrot(DDName(rotNameNippleToCover, "pixfwdNipple"),
0408 make_unique<DDRotationMatrix>(
0409 rpNC.xx(), rpNC.xy(), rpNC.xz(), rpNC.yx(), rpNC.yy(), rpNC.yz(), rpNC.zx(), rpNC.zy(), rpNC.zz()));
0410 edm::LogVerbatim("PixelGeom") << "DDPixFwdBlades::Defines " << DDName(rotNameNippleToCover, "pixfwdNipple")
0411 << " with " << rpNC;
0412
0413
0414
0415 CLHEP::HepRotation rpNB(rpNC * rCB);
0416
0417 DDrot(DDName(rotNameNippleToBody, "pixfwdNipple"),
0418 make_unique<DDRotationMatrix>(
0419 rpNB.xx(), rpNB.xy(), rpNB.xz(), rpNB.yx(), rpNB.yy(), rpNB.yz(), rpNB.zx(), rpNB.zy(), rpNB.zz()));
0420 edm::LogVerbatim("PixelGeom") << "DDPixFwdBlades::Defines " << DDName(rotNameNippleToBody, "pixfwdNipple") << " with "
0421 << rpNB;
0422 double angleBody = vZ.angle(rpNB * vZ);
0423 edm::LogVerbatim("PixelGeom") << " Angle to body : " << angleBody;
0424 }
0425
0426 DEFINE_EDM_PLUGIN(DDAlgorithmFactory, DDPixFwdBlades, "track:DDPixFwdBlades");