CMS 3D CMS Logo

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