CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch13/src/Geometry/TrackerCommonData/src/DDPixFwdBlades.cc

Go to the documentation of this file.
00001 /* 
00002 == CMS Forward Pixels Geometry ==
00003 
00004  @version 3.02.01 May 30, 2006
00005  @created Dmitry Onoprienko
00006 
00007   Algorithm for placing one-per-blade components.
00008   See header file (DDPixFwdBlades.h) for a detailed description.
00009 */
00010 
00011 #include <cmath>
00012 #include <algorithm>
00013 
00014 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00015 #include "DetectorDescription/Base/interface/DDRotationMatrix.h"
00016 #include "DetectorDescription/Base/interface/DDutils.h"
00017 #include "DetectorDescription/Core/interface/DDLogicalPart.h"
00018 #include "DetectorDescription/Core/interface/DDSolid.h"
00019 #include "DetectorDescription/Core/interface/DDMaterial.h"
00020 #include "DetectorDescription/Core/interface/DDCurrentNamespace.h"
00021 #include "DetectorDescription/Core/interface/DDSplit.h"
00022 #include "DetectorDescription/Core/interface/DDConstant.h"
00023 #include "Geometry/TrackerCommonData/interface/DDPixFwdBlades.h"
00024 #include "CLHEP/Vector/RotationInterfaces.h"
00025 #include "CLHEP/Units/GlobalPhysicalConstants.h"
00026 #include "CLHEP/Units/GlobalSystemOfUnits.h"
00027 
00028   // -- Input geometry parameters :  -----------------------------------------------------
00029 
00030 const int DDPixFwdBlades::nBlades = 24;                     // Number of blades
00031 const double DDPixFwdBlades::bladeAngle = 20.*CLHEP::deg;   // Angle of blade rotation around its axis
00032 const double DDPixFwdBlades::zPlane = 0.;                   // Common shift in Z for all blades (with respect to disk center plane)
00033 const double DDPixFwdBlades::bladeZShift = 6.*CLHEP::mm;    // Shift in Z between the axes of two adjacent blades
00034   
00035 const double DDPixFwdBlades::ancorRadius = 54.631*CLHEP::mm;// Distance from beam line to ancor point defining center of "blade frame"
00036   
00037 // Coordinates of Nipple ancor points J and K in "blade frame" :
00038 
00039 const double DDPixFwdBlades::jX = -16.25*CLHEP::mm;
00040 const double DDPixFwdBlades::jY = 96.50*CLHEP::mm;
00041 const double DDPixFwdBlades::jZ = 1.25*CLHEP::mm;
00042 const double DDPixFwdBlades::kX = 16.25*CLHEP::mm;
00043 const double DDPixFwdBlades::kY = 96.50*CLHEP::mm;
00044  const double DDPixFwdBlades::kZ = -1.25*CLHEP::mm;
00045   
00046 // -- Static initialization :  -----------------------------------------------------------
00047 
00048 CLHEP::HepRotation* DDPixFwdBlades::nippleRotationZPlus = 0;
00049 CLHEP::HepRotation* DDPixFwdBlades::nippleRotationZMinus = 0;
00050 double DDPixFwdBlades::nippleTranslationX = 0.;
00051 double DDPixFwdBlades::nippleTranslationY = 0.;
00052 double DDPixFwdBlades::nippleTranslationZ = 0.;
00053 
00054 std::map<std::string, int> DDPixFwdBlades::copyNumbers;
00055 
00056 // -- Constructors & Destructor :  -------------------------------------------------------
00057 
00058 DDPixFwdBlades::DDPixFwdBlades() {}
00059 DDPixFwdBlades::~DDPixFwdBlades() {}
00060 
00061 // Initialization :  ---------------------------------------------------------------------
00062 
00063 void DDPixFwdBlades::initialize(const DDNumericArguments & nArgs,
00064                                 const DDVectorArguments & vArgs,
00065                                 const DDMapArguments & ,
00066                                 const DDStringArguments & sArgs,
00067                                 const DDStringVectorArguments & ) {
00068                                         
00069   if ( nArgs.find("Endcap") != nArgs.end() ) {
00070     endcap = nArgs["Endcap"];
00071   } else {
00072     endcap = 1.;
00073   }
00074 
00075   if ( sArgs.find("FlagString") != sArgs.end() ) {
00076     flagString = sArgs["FlagString"];
00077     flagSelector = sArgs["FlagSelector"];
00078   } else {
00079     flagString = "YYYYYYYYYYYYYYYYYYYYYYYY";
00080     flagSelector = "Y";
00081   }
00082 
00083   if ( sArgs.find("Child") != sArgs.end() ) {
00084     childName   = sArgs["Child"];
00085   } else {
00086     childName   = "";
00087   }
00088 
00089   if ( vArgs.find("ChildTranslation") != vArgs.end() ) {
00090     childTranslationVector = vArgs["ChildTranslation"];
00091   } else {
00092     childTranslationVector = std::vector<double>(3, 0.);
00093   }
00094 
00095   if ( sArgs.find("ChildRotation") != sArgs.end() ) {
00096     childRotationName = sArgs["ChildRotation"];
00097   } else {
00098     childRotationName = "";
00099   }
00100 
00101   idNameSpace = DDCurrentNamespace::ns();
00102 }
00103   
00104 // Execution :  --------------------------------------------------------------------------
00105 
00106 void DDPixFwdBlades::execute(DDCompactView& cpv) {
00107 
00108   // -- Compute Nipple parameters if not already computed :
00109   
00110   if (!nippleRotationZPlus) {
00111     computeNippleParameters(1.);   // Z Plus endcap
00112     computeNippleParameters(-1.);  // Z Minus endcap
00113   }
00114   if (childName == "") return;
00115   
00116   // -- Signed versions of blade angle and z-shift :
00117   
00118   double effBladeAngle = - endcap * bladeAngle;
00119   double effBladeZShift = endcap * bladeZShift;
00120   
00121   // -- Names of mother and child volumes :
00122 
00123   DDName mother = parent().name();
00124   DDName child(DDSplit(childName).first, DDSplit(childName).second);
00125   
00126   // -- Get translation and rotation from "blade frame" to "child frame", if any :
00127   
00128   CLHEP::HepRotation childRotMatrix = CLHEP::HepRotation();
00129   if (childRotationName != "") {
00130     DDRotation childRotation = DDRotation(DDName(DDSplit(childRotationName).first, DDSplit(childRotationName).second));
00131     // due to conversion to ROOT::Math::Rotation3D -- Michael Case
00132     DD3Vector x, y, z;
00133     childRotation.rotation()->GetComponents(x, y, z); // these are the orthonormal columns.
00134     CLHEP::HepRep3x3 tr(x.X(), y.X(), z.X(), x.Y(), y.Y(), z.Y(), x.Z(), y.Z(), z.Z());
00135     childRotMatrix = CLHEP::HepRotation(tr);
00136   } else if (childName == "pixfwdNipple:PixelForwardNippleZPlus") {
00137     childRotMatrix = *nippleRotationZPlus;
00138   } else if (childName == "pixfwdNipple:PixelForwardNippleZMinus") {
00139     childRotMatrix = *nippleRotationZMinus;
00140   }
00141   
00142   CLHEP::Hep3Vector childTranslation;
00143   if (childName == "pixfwdNipple:PixelForwardNippleZPlus") {
00144     childTranslation = CLHEP::Hep3Vector(nippleTranslationX, nippleTranslationY, nippleTranslationZ);
00145   } else if (childName == "pixfwdNipple:PixelForwardNippleZMinus") {
00146     childTranslation = CLHEP::Hep3Vector(-nippleTranslationX, nippleTranslationY, nippleTranslationZ);
00147   } else {
00148     childTranslation = CLHEP::Hep3Vector(childTranslationVector[0],childTranslationVector[1],childTranslationVector[2]);
00149   }
00150   
00151   // Create a matrix for rotation around blade axis (to "blade frame") :
00152   
00153   CLHEP::HepRotation bladeRotMatrix(CLHEP::Hep3Vector(0.,1.,0.),effBladeAngle);
00154   
00155   // Cycle over Phi positions, placing copies of the child volume :
00156 
00157   double deltaPhi = (360./nBlades)*CLHEP::deg;
00158   int nQuarter = nBlades/4;
00159   double zShiftMax = effBladeZShift*((nQuarter-1)/2.);
00160 
00161   for (int iBlade=0; iBlade < nBlades; iBlade++) {
00162     
00163     // check if this blade position should be skipped :
00164         
00165     if (flagString[iBlade] != flagSelector[0]) continue;
00166     int copy = issueCopyNumber();
00167     
00168     // calculate Phi and Z shift for this blade :
00169 
00170     double phi = (iBlade + 0.5) * deltaPhi - 90.*CLHEP::deg;
00171     int iQuarter = iBlade % nQuarter;
00172     double zShift = - zShiftMax + iQuarter * effBladeZShift;
00173     
00174     // compute rotation matrix from mother to blade frame :
00175     
00176     CLHEP::HepRotation rotMatrix(CLHEP::Hep3Vector(0.,0.,1.), phi);
00177     rotMatrix *= bladeRotMatrix;
00178 
00179     // convert translation vector from blade frame to mother frame, and add Z shift :
00180     
00181     CLHEP::Hep3Vector translation = rotMatrix(childTranslation + CLHEP::Hep3Vector(0., ancorRadius, 0.));
00182     translation += CLHEP::Hep3Vector(0., 0., zShift + zPlane);
00183     
00184     // create DDRotation for placing the child if not already existent :
00185 
00186     DDRotation rotation;   
00187     std::string rotstr = DDSplit(childName).first + int_to_string(copy);
00188     rotation = DDRotation(DDName(rotstr, idNameSpace));
00189 
00190     if (!rotation) {
00191       rotMatrix *= childRotMatrix;
00192       DDRotationMatrix* temp = new DDRotationMatrix(rotMatrix.xx(), rotMatrix.xy(), rotMatrix.xz(),
00193                                                     rotMatrix.yx(), rotMatrix.yy(), rotMatrix.yz(),
00194                                                     rotMatrix.zx(), rotMatrix.zy(), rotMatrix.zz() );
00195       rotation = DDrot(DDName(rotstr, idNameSpace), temp);
00196     }
00197     // position the child :
00198 
00199     DDTranslation ddtran(translation.x(), translation.y(), translation.z());
00200     cpv.position(child, mother, copy, ddtran, rotation);
00201     // LogDebug("PixelGeom") << "DDPixFwdBlades: " << child << " Copy " << copy << " positioned in " << mother << " at " << translation << " with rotation " << rotation;
00202   }
00203 
00204   // End of cycle over Phi positions
00205 
00206 }
00207 
00208 // -- Helpers :  -------------------------------------------------------------------------
00209 
00210 int DDPixFwdBlades::issueCopyNumber() {
00211   if (copyNumbers.count(childName) == 0) copyNumbers[childName] = 0;
00212   return ++copyNumbers[childName];
00213 }
00214 
00215 
00216 // -- Calculating Nipple parameters :  ---------------------------------------------------
00217 
00218 void DDPixFwdBlades::computeNippleParameters(double endcap) {
00219         
00220   double effBladeAngle = endcap * bladeAngle;
00221   
00222   CLHEP::Hep3Vector jC; // Point J in the "cover" blade frame
00223   CLHEP::Hep3Vector kB; // Point K in the "body" blade frame
00224   std::string rotNameNippleToCover;
00225   std::string rotNameCoverToNipple;
00226   std::string rotNameNippleToBody;
00227 
00228   if (endcap > 0.) {
00229     jC = CLHEP::Hep3Vector(jX, jY + ancorRadius, jZ);
00230     kB = CLHEP::Hep3Vector(kX, kY + ancorRadius, kZ);
00231     rotNameNippleToCover = "NippleToCoverZPlus";
00232     rotNameCoverToNipple = "CoverToNippleZPlus";
00233     rotNameNippleToBody = "NippleToBodyZPlus";
00234   } else {
00235     jC = CLHEP::Hep3Vector(-jX, jY + ancorRadius, jZ);
00236     kB = CLHEP::Hep3Vector(-kX, kY + ancorRadius, kZ);
00237     rotNameNippleToCover = "NippleToCoverZMinus";
00238     rotNameCoverToNipple = "CoverToNippleZMinus";
00239     rotNameNippleToBody = "NippleToBodyZMinus";
00240   }
00241                 
00242   // Z-shift from "cover" to "body" blade frame:
00243   
00244   CLHEP::Hep3Vector tCB(bladeZShift*sin(effBladeAngle), 0., bladeZShift*cos(effBladeAngle));
00245   
00246   // Rotation from "cover" blade frame into "body" blade frame :
00247   
00248   double deltaPhi = endcap*(360./nBlades)*CLHEP::deg;
00249   CLHEP::HepRotation rCB(CLHEP::Hep3Vector(1.*sin(effBladeAngle), 0., 1.*cos(effBladeAngle)), deltaPhi);
00250   
00251   // Transform vector k into "cover" blade frame :
00252   
00253   CLHEP::Hep3Vector kC = rCB * (kB + tCB);
00254   
00255   // Vector JK in the "cover" blade frame:
00256   
00257   CLHEP::Hep3Vector jkC = kC - jC;
00258   double* jkLength = new double(jkC.mag());
00259   DDConstant JK(DDName("JK", "pixfwdNipple"), jkLength);
00260   LogDebug("PixelGeom") << "+++++++++++++++ DDPixFwdBlades: " << "JK Length " <<  *jkLength * CLHEP::mm;
00261   
00262   // Position of the center of a nipple in "cover" blade frame :
00263   
00264   CLHEP::Hep3Vector nippleTranslation((kC+jC)/2. - CLHEP::Hep3Vector(0., ancorRadius, 0.));
00265   if (endcap > 0) {
00266     nippleTranslationX = nippleTranslation.x();
00267     nippleTranslationY = nippleTranslation.y();
00268     nippleTranslationZ = nippleTranslation.z();
00269   }
00270   LogDebug("PixelGeom") << "Child translation : " << nippleTranslation;
00271   
00272   // Rotations from nipple frame to "cover" blade frame and back :
00273   
00274   CLHEP::Hep3Vector vZ(0.,0.,1.);
00275   CLHEP::Hep3Vector axis = vZ.cross(jkC);
00276   double angleCover = vZ.angle(jkC);
00277   LogDebug("PixelGeom") << " Angle to Cover: " << angleCover;
00278   CLHEP::HepRotation* rpCN = new CLHEP::HepRotation(axis, angleCover);
00279   if (endcap > 0.) {
00280     nippleRotationZPlus = rpCN;
00281   } else {
00282     nippleRotationZMinus = rpCN;
00283   }
00284   //( endcap > 0. ? nippleRotationZPlus : nippleRotationZMinus ) = rpCN;
00285 
00286   DDRotationMatrix* ddrpCN = new DDRotationMatrix(rpCN->xx(), rpCN->xy(), rpCN->xz(),
00287                                                   rpCN->yx(), rpCN->yy(), rpCN->yz(),
00288                                                   rpCN->zx(), rpCN->zy(), rpCN->zz() );
00289 
00290   DDrot(DDName(rotNameCoverToNipple, "pixfwdNipple"), ddrpCN);
00291   CLHEP::HepRotation rpNC(axis, -angleCover);
00292   DDRotationMatrix* ddrpNC = new DDRotationMatrix(rpNC.xx(), rpNC.xy(), rpNC.xz(),
00293                                                   rpNC.yx(), rpNC.yy(), rpNC.yz(),
00294                                                   rpNC.zx(), rpNC.zy(), rpNC.zz() );
00295 
00296   DDrot(DDName(rotNameNippleToCover, "pixfwdNipple"), ddrpNC);
00297   
00298   // Rotation from nipple frame to "body" blade frame :
00299   
00300   CLHEP::HepRotation rpNB( rpNC * rCB );
00301   DDRotationMatrix* ddrpNB = new DDRotationMatrix(rpNB.xx(), rpNB.xy(), rpNB.xz(),
00302                                                   rpNB.yx(), rpNB.yy(), rpNB.yz(),
00303                                                   rpNB.zx(), rpNB.zy(), rpNB.zz() );
00304 
00305   DDrot(DDName(rotNameNippleToBody, "pixfwdNipple"), ddrpNB);
00306   double angleBody = vZ.angle(rpNB * vZ);
00307   LogDebug("PixelGeom") << " Angle to body : " << angleBody;  
00308 }
00309 
00310 // ---------------------------------------------------------------------------------------
00311