Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:15:21

0001 #include "DD4hep/DetFactoryHelper.h"
0002 #include <DD4hep/DD4hepUnits.h>
0003 #include "DataFormats/Math/interface/angle_units.h"
0004 #include "DetectorDescription/DDCMS/interface/DDPlugins.h"
0005 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0006 
0007 using namespace std;
0008 using namespace dd4hep;
0009 using namespace cms;
0010 using namespace angle_units::operators;
0011 
0012 static long algorithm(Detector& /* description */, cms::DDParsingContext& ctxt, xml_h e) {
0013   cms::DDNamespace ns(ctxt, e, true);
0014   DDAlgoArguments args(ctxt, e);
0015   Volume mother = ns.volume(args.parentName());
0016 
0017   //variables:
0018   //double         noOverlapShift   = args.value<double>("NoOverlapShift");
0019   int ringNo = args.value<int>("RingNo");
0020   bool isStereo = args.value<int>("isStereo") == 1;
0021   bool isRing6 = (ringNo == 6);
0022   double rPos =
0023       args.value<double>("RPos");  //Position in R relativ to the center of the TEC ( this is the coord-sys of Tubs)
0024   double posCorrectionPhi = isStereo ? args.value<double>("PosCorrectionPhi")
0025                                      : 0e0;  // the Phi position of the stereo Modules has to be corrected
0026   string standardRot = args.value<string>(
0027       "StandardRotation");  //Rotation that aligns the mother(Tub ) coordinate System with the components
0028   string genMat = args.value<string>("GeneralMaterial");                              //General material name
0029   double moduleThick = args.value<double>("ModuleThick");                             //Module thickness
0030   double detTilt = args.value<double>("DetTilt");                                     //Tilt of stereo detector
0031   double fullHeight = args.value<double>("FullHeight");                               //Height
0032   double dlTop = args.value<double>("DlTop");                                         //Width at top of wafer
0033   double dlBottom = args.value<double>("DlBottom");                                   //Width at bottom of wafer
0034   double dlHybrid = args.value<double>("DlHybrid");                                   //Width at the hybrid end
0035   double frameWidth = args.value<double>("FrameWidth");                               //Frame         width
0036   double frameThick = args.value<double>("FrameThick");                               //              thickness
0037   double frameOver = args.value<double>("FrameOver");                                 //              overlap (on sides)
0038   string topFrameMat = args.value<string>("TopFrameMaterial");                        //Top frame     material
0039   double topFrameHeight = args.value<double>("TopFrameHeight");                       //              height
0040   double topFrameThick = args.value<double>("TopFrameThick");                         //              thickness
0041   double topFrameTopWidth = args.value<double>("TopFrameTopWidth");                   //             Width at the top
0042   double topFrameBotWidth = args.value<double>("TopFrameBotWidth");                   //             Width at the bottom
0043   double topFrame2Width = isStereo ? args.value<double>("TopFrame2Width") : 0e0;      //  Stereo:2ndPart   Width
0044   double topFrame2LHeight = isStereo ? args.value<double>("TopFrame2LHeight") : 0e0;  //             left  height
0045   double topFrame2RHeight = isStereo ? args.value<double>("TopFrame2RHeight") : 0e0;  //             right height
0046   double topFrameZ = args.value<double>("TopFrameZ");                                 //              z-positions
0047 
0048   double resizeH = 0.96;
0049   string sideFrameMat = args.value<string>("SideFrameMaterial");   //Side frame    material
0050   double sideFrameThick = args.value<double>("SideFrameThick");    //              thickness
0051   double sideFrameLWidth = args.value<double>("SideFrameLWidth");  //    Left     Width (for stereo modules upper one)
0052   double sideFrameLWidthLow = isStereo ? args.value<double>("SideFrameLWidthLow")
0053                                        : 0e0;  //           Width (only for stereo modules: lower Width)
0054   double sideFrameLHeight = resizeH * args.value<double>("SideFrameLHeight");  //             Height
0055   double sideFrameLtheta = args.value<double>("SideFrameLtheta");  //              angle of the trapezoid shift
0056   double sideFrameRWidth = args.value<double>("SideFrameRWidth");  //    Right    Width (for stereo modules upper one)
0057   double sideFrameRWidthLow = isStereo ? args.value<double>("SideFrameRWidthLow")
0058                                        : 0e0;  //           Width (only for stereo modules: lower Width)
0059   double sideFrameRHeight = resizeH * args.value<double>("SideFrameRHeight");  //             Height
0060   double sideFrameRtheta = args.value<double>("SideFrameRtheta");  //              angle of the trapezoid shift
0061   vector<double> siFrSuppBoxWidth = args.value<vector<double> >("SiFrSuppBoxWidth");    //    Supp.Box Width
0062   vector<double> siFrSuppBoxHeight = args.value<vector<double> >("SiFrSuppBoxHeight");  //            Height
0063   vector<double> siFrSuppBoxYPos = args.value<vector<double> >(
0064       "SiFrSuppBoxYPos");  //              y-position of the supplies box (with HV an thermal sensor...)
0065   double sideFrameZ = args.value<double>("SideFrameZ");               //              z-positions
0066   double siFrSuppBoxThick = args.value<double>("SiFrSuppBoxThick");   //             thickness
0067   string siFrSuppBoxMat = args.value<string>("SiFrSuppBoxMaterial");  //              material
0068   string waferMat = args.value<string>("WaferMaterial");              //Wafer         material
0069   double waferPosition = args.value<double>(
0070       "WaferPosition");  //              position of the wafer (was formaly done by adjusting topFrameHeigt)
0071   double sideWidthTop = args.value<double>("SideWidthTop");        //              widths on the side Top
0072   double sideWidthBottom = args.value<double>("SideWidthBottom");  //                                 Bottom
0073   string waferRot = args.value<string>("WaferRotation");           //              rotation matrix
0074   string activeMat = args.value<string>("ActiveMaterial");         //Sensitive     material
0075   double activeHeight = args.value<double>("ActiveHeight");        //              height
0076   double waferThick = args.value<double>("WaferThick");     //              wafer thickness (active = wafer - backplane)
0077   string activeRot = args.value<string>("ActiveRotation");  //              Rotation matrix
0078   double activeZ = args.value<double>("ActiveZ");           //              z-positions
0079   double backplaneThick = args.value<double>("BackPlaneThick");               //              thickness
0080   double inactiveDy = ringNo > 3 ? args.value<double>("InactiveDy") : 0e0;    //InactiveStrip  Hight of ( rings > 3)
0081   double inactivePos = ringNo > 3 ? args.value<double>("InactivePos") : 0e0;  //               y-Position
0082   string inactiveMat = ringNo > 3 ? args.value<string>("InactiveMaterial") : string();  //               material
0083   string hybridMat = args.value<string>("HybridMaterial");                              //Hybrid        material
0084   double hybridHeight = args.value<double>("HybridHeight");                             //              height
0085   double hybridWidth = args.value<double>("HybridWidth");                               //              width
0086   double hybridThick = args.value<double>("HybridThick");                               //              thickness
0087   double hybridZ = args.value<double>("HybridZ");                                       //              z-positions
0088   string pitchMat = args.value<string>("PitchMaterial");                                //Pitch adapter material
0089   double pitchWidth = args.value<double>("PitchWidth");                                 //              width
0090   double pitchHeight = args.value<double>("PitchHeight");                               //              height
0091   double pitchThick = args.value<double>("PitchThick");                                 //              thickness
0092   double pitchZ = args.value<double>("PitchZ");                                         //              z-positions
0093   string pitchRot = args.value<string>("PitchRotation");                                //              rotation matrix
0094   string bridgeMat = args.value<string>("BridgeMaterial");                              //Bridge        material
0095   double bridgeWidth = args.value<double>("BridgeWidth");                               //              width
0096   double bridgeThick = args.value<double>("BridgeThick");                               //              thickness
0097   double bridgeHeight = args.value<double>("BridgeHeight");                             //              height
0098   double bridgeSep = args.value<double>("BridgeSeparation");                            //              separation
0099   vector<double> siReenforceHeight = args.value<vector<double> >("SiReenforcementHeight");  // SiReenforcement Height
0100   vector<double> siReenforceWidth = args.value<vector<double> >("SiReenforcementWidth");    //             Width
0101   vector<double> siReenforceYPos = args.value<vector<double> >("SiReenforcementPosY");      //              Y - Position
0102   double siReenforceThick = args.value<double>("SiReenforcementThick");                     //             Thick
0103   string siReenforceMat = args.value<string>("SiReenforcementMaterial");                    //             Materieal
0104 
0105   edm::LogVerbatim("TECGeom") << "debug: ModuleThick " << moduleThick << " Detector Tilt " << convertRadToDeg(detTilt)
0106                               << " Height " << fullHeight << " dl(Top) " << dlTop << " dl(Bottom) " << dlBottom
0107                               << " dl(Hybrid) " << dlHybrid << " rPos " << rPos << " standrad rotation " << standardRot;
0108   edm::LogVerbatim("TECGeom") << "debug: Frame Width " << frameWidth << " Thickness " << frameThick << " Overlap "
0109                               << frameOver;
0110   edm::LogVerbatim("TECGeom") << "debug: Top Frame Material " << topFrameMat << " Height " << topFrameHeight
0111                               << " Top Width " << topFrameTopWidth << " Bottom Width " << topFrameTopWidth
0112                               << " Thickness " << topFrameThick << " positioned at" << topFrameZ;
0113   edm::LogVerbatim("TECGeom") << "debug : Side Frame Material " << sideFrameMat << " Thickness " << sideFrameThick
0114                               << " left Leg's Width: " << sideFrameLWidth << " left Leg's Height: " << sideFrameLHeight
0115                               << " left Leg's tilt(theta): " << sideFrameLtheta
0116                               << " right Leg's Width: " << sideFrameRWidth
0117                               << " right Leg's Height: " << sideFrameRHeight
0118                               << " right Leg's tilt(theta): " << sideFrameRtheta
0119                               << "Supplies Box's Material: " << siFrSuppBoxMat << " positioned at" << sideFrameZ;
0120   for (int i = 0; i < (int)(siFrSuppBoxWidth.size()); i++)
0121     edm::LogVerbatim("TECGeom") << " Supplies Box" << i << "'s Width: " << siFrSuppBoxWidth[i] << " Supplies Box" << i
0122                                 << "'s Height: " << siFrSuppBoxHeight[i] << " Supplies Box" << i
0123                                 << "'s y Position: " << siFrSuppBoxYPos[i];
0124   edm::LogVerbatim("TECGeom") << "debug: Wafer Material " << waferMat << " Side Width Top" << sideWidthTop
0125                               << " Side Width Bottom" << sideWidthBottom << " and positioned at " << waferPosition
0126                               << " positioned with rotation"
0127                               << " matrix:" << waferRot;
0128   edm::LogVerbatim("TECGeom") << "debug: Active Material " << activeMat << " Height " << activeHeight << " rotated by "
0129                               << activeRot << " translated by (0,0," << -0.5 * backplaneThick << ")"
0130                               << " Thickness/Z" << waferThick - backplaneThick << "/" << activeZ;
0131   edm::LogVerbatim("TECGeom") << "debug: Hybrid Material " << hybridMat << " Height " << hybridHeight << " Width "
0132                               << hybridWidth << " Thickness " << hybridThick << " Z" << hybridZ;
0133   edm::LogVerbatim("TECGeom") << "debug: Pitch Adapter Material " << pitchMat << " Height " << pitchHeight
0134                               << " Thickness " << pitchThick << " position with "
0135                               << " rotation " << pitchRot << " at Z" << pitchZ;
0136   edm::LogVerbatim("TECGeom") << "debug: Bridge Material " << bridgeMat << " Width " << bridgeWidth << " Thickness "
0137                               << bridgeThick << " Height " << bridgeHeight << " Separation " << bridgeSep;
0138   edm::LogVerbatim("TECGeom") << "FALTBOOT DDTECModuleAlgo debug : Si-Reenforcement Material " << sideFrameMat
0139                               << " Thickness " << siReenforceThick;
0140   for (int i = 0; i < (int)(siReenforceWidth.size()); i++)
0141     edm::LogVerbatim("TECGeom") << " SiReenforcement" << i << "'s Width: " << siReenforceWidth[i] << " SiReenforcement"
0142                                 << i << "'s Height: " << siReenforceHeight[i] << " SiReenforcement" << i
0143                                 << "'s y Position: " << siReenforceYPos[i];
0144 
0145   if (!isStereo) {
0146     edm::LogVerbatim("TECGeom") << "This is a normal module, in ring " << ringNo << "!";
0147   } else {
0148     edm::LogVerbatim("TECGeom") << "This is a stereo module, in ring " << ringNo << "!";
0149     edm::LogVerbatim("TECGeom") << "Phi Position corrected by " << posCorrectionPhi << "*rad";
0150     edm::LogVerbatim("TECGeom") << "debug: stereo Top Frame 2nd Part left Heigt " << topFrame2LHeight
0151                                 << " right Height " << topFrame2RHeight << " Width " << topFrame2Width;
0152     edm::LogVerbatim("TECGeom") << " left Leg's lower Width: " << sideFrameLWidthLow
0153                                 << " right Leg's lower Width: " << sideFrameRWidthLow;
0154   }
0155 
0156   // Execution part:
0157 
0158   edm::LogVerbatim("TECGeom") << "==>> Constructing DDTECModuleAlgo: ";
0159   //declarations
0160   double tmp;
0161   //names
0162   string name;
0163   string tag("Rphi");
0164   if (isStereo)
0165     tag = "Stereo";
0166   //usefull constants
0167   const double topFrameEndZ = 0.5 * (-waferPosition + fullHeight) + pitchHeight + hybridHeight - topFrameHeight;
0168   string idName = ns.noNamespace(mother.name());
0169   edm::LogVerbatim("TECGeom") << "idName: " << idName << " parent " << mother.name() << " namespace " << ns.name();
0170   Solid solid;
0171 
0172   //set global parameters
0173   Material matter = ns.material(genMat);
0174   double dzdif = fullHeight + topFrameHeight;
0175   if (isStereo)
0176     dzdif += 0.5 * (topFrame2LHeight + topFrame2RHeight);
0177 
0178   double dxbot = 0.5 * dlBottom + frameWidth - frameOver;
0179   double dxtop = 0.5 * dlHybrid + frameWidth - frameOver;
0180   //  topfr = 0.5*dlBottom * sin(detTilt);
0181   if (isRing6) {
0182     dxbot = dxtop;
0183     dxtop = 0.5 * dlTop + frameWidth - frameOver;
0184     //    topfr = 0.5*dlTop    * sin(detTilt);
0185   }
0186   double dxdif = dxtop - dxbot;
0187 
0188   //Frame Sides
0189   // left Frame
0190   name = idName + "SideFrameLeft";
0191   double h1 = 0.5 * sideFrameThick;
0192   double dz = 0.5 * sideFrameLHeight;
0193   double bl1 = 0.5 * sideFrameLWidth;
0194   double bl2 = bl1;
0195   double thet = sideFrameLtheta;
0196   //for stereo modules
0197   if (isStereo)
0198     bl1 = 0.5 * sideFrameLWidthLow;
0199   solid = Trap(dz, thet, 0, h1, bl1, bl1, 0, h1, bl2, bl2, 0);
0200   ns.addSolidNS(ns.prepend(name), solid);
0201   edm::LogVerbatim("TECGeom") << "Solid: " << name << " " << solid.name() << " Trap made of " << sideFrameMat
0202                               << " of dimensions " << dz << ",  " << thet << ", 0, " << h1 << ", " << bl1 << ", " << bl1
0203                               << ", 0, " << h1 << ", " << bl2 << ", " << bl2 << ", 0";
0204   Volume sideFrameLeft(ns.prepend(name), solid, ns.material(sideFrameMat));
0205   ns.addVolumeNS(sideFrameLeft);
0206   //translate
0207   double xpos = -0.5 * topFrameBotWidth + bl2 + tan(fabs(thet)) * dz;
0208   double ypos = sideFrameZ;
0209   double zpos = topFrameEndZ - dz;
0210   //flip ring 6
0211   if (isRing6) {
0212     zpos *= -1;
0213     xpos -= 2 * tan(fabs(thet)) * dz;  // because of the flip the tan(..) to be in the other direction
0214   }
0215   //the stereo modules are on the back of the normal ones...
0216   if (isStereo) {
0217     xpos = -0.5 * topFrameBotWidth + bl2 * cos(detTilt) + dz * sin(fabs(thet) + detTilt) / cos(fabs(thet));
0218     xpos = -xpos;
0219     zpos = topFrameEndZ - topFrame2LHeight - 0.5 * sin(detTilt) * (topFrameBotWidth - topFrame2Width) -
0220            dz * cos(detTilt + fabs(thet)) / cos(fabs(thet)) + bl2 * sin(detTilt) - 0.1 * dd4hep::mm;
0221   }
0222   //position
0223   mother.placeVolume(
0224       sideFrameLeft,
0225       isStereo ? 2 : 1,
0226       dd4hep::Transform3D(ns.rotation(waferRot),
0227                           dd4hep::Position(zpos + rPos, isStereo ? xpos + rPos * sin(posCorrectionPhi) : xpos, ypos)));
0228 
0229   //right Frame
0230   name = idName + "SideFrameRight";
0231   h1 = 0.5 * sideFrameThick;
0232   dz = 0.5 * sideFrameRHeight;
0233   bl1 = bl2 = 0.5 * sideFrameRWidth;
0234   thet = sideFrameRtheta;
0235   if (isStereo)
0236     bl1 = 0.5 * sideFrameRWidthLow;
0237   solid = Trap(dz, thet, 0, h1, bl1, bl1, 0, h1, bl2, bl2, 0);
0238   ns.addSolidNS(ns.prepend(name), solid);
0239   edm::LogVerbatim("TECGeom") << "Solid:\t" << name << " " << solid.name() << " Trap made of " << sideFrameMat
0240                               << " of dimensions " << dz << ", " << thet << ", 0, " << h1 << ", " << bl1 << ", " << bl1
0241                               << ", 0, " << h1 << ", " << bl2 << ", " << bl2 << ", 0";
0242   Volume sideFrameRight(ns.prepend(name), solid, ns.material(sideFrameMat));
0243   ns.addVolumeNS(sideFrameRight);
0244   //translate
0245   xpos = 0.5 * topFrameBotWidth - bl2 - tan(fabs(thet)) * dz;
0246   ypos = sideFrameZ;
0247   zpos = topFrameEndZ - dz;
0248   if (isRing6) {
0249     zpos *= -1;
0250     xpos += 2 * tan(fabs(thet)) * dz;  // because of the flip the tan(..) has to be in the other direction
0251   }
0252   if (isStereo) {
0253     xpos = 0.5 * topFrameBotWidth - bl2 * cos(detTilt) - dz * sin(fabs(detTilt - fabs(thet))) / cos(fabs(thet));
0254     xpos = -xpos;
0255     zpos = topFrameEndZ - topFrame2RHeight + 0.5 * sin(detTilt) * (topFrameBotWidth - topFrame2Width) -
0256            dz * cos(detTilt - fabs(thet)) / cos(fabs(thet)) - bl2 * sin(detTilt) - 0.1 * dd4hep::mm;
0257   }
0258   //position it
0259   mother.placeVolume(
0260       sideFrameRight,
0261       isStereo ? 2 : 1,
0262       dd4hep::Transform3D(ns.rotation(waferRot),
0263                           dd4hep::Position(zpos + rPos, isStereo ? xpos + rPos * sin(posCorrectionPhi) : xpos, ypos)));
0264   //Supplies Box(es)
0265   matter = ns.material(siFrSuppBoxMat);
0266   for (int i = 0; i < (int)(siFrSuppBoxWidth.size()); i++) {
0267     name = idName + "SuppliesBox" + std::to_string(i);
0268 
0269     h1 = 0.5 * siFrSuppBoxThick;
0270     dz = 0.5 * siFrSuppBoxHeight[i];
0271     bl1 = bl2 = 0.5 * siFrSuppBoxWidth[i];
0272     thet = sideFrameRtheta;
0273     if (isStereo)
0274       thet = -atan(fabs(sideFrameRWidthLow - sideFrameRWidth) / (2 * sideFrameRHeight) - tan(fabs(thet)));
0275     // ^-- this calculates the lower left angel of the tipped trapezoid, which is the SideFframe...
0276 
0277     solid = Trap(dz, thet, 0, h1, bl1, bl1, 0, h1, bl2, bl2, 0);
0278     ns.addSolidNS(ns.prepend(name), solid);
0279     edm::LogVerbatim("TECGeom") << "Solid:\t" << name << " " << solid.name() << " Trap made of " << siFrSuppBoxMat
0280                                 << " of dimensions " << dz << ", 0, 0, " << h1 << ", " << bl1 << ", " << bl1 << ", 0, "
0281                                 << h1 << ", " << bl2 << ", " << bl2 << ", 0";
0282     Volume siFrSuppBox(ns.prepend(name), solid, matter);
0283     ns.addVolumeNS(siFrSuppBox);
0284     //translate
0285     xpos = 0.5 * topFrameBotWidth - sideFrameRWidth - bl1 - siFrSuppBoxYPos[i] * tan(fabs(thet));
0286     ypos = sideFrameZ *
0287            (0.5 + (siFrSuppBoxThick / sideFrameThick));  //via * so I do not have to worry about the sign of sideFrameZ
0288     zpos = topFrameEndZ - siFrSuppBoxYPos[i];
0289     if (isRing6) {
0290       xpos += 2 * fabs(tan(thet)) * siFrSuppBoxYPos[i];  // the flipped issue again
0291       zpos *= -1;
0292     }
0293     if (isStereo) {
0294       xpos = 0.5 * topFrameBotWidth - (sideFrameRWidth + bl1) * cos(detTilt) -
0295              sin(fabs(detTilt - fabs(thet))) *
0296                  (siFrSuppBoxYPos[i] + dz * (1 / cos(thet) - cos(detTilt)) + bl1 * sin(detTilt));
0297       xpos = -xpos;
0298       zpos = topFrameEndZ - topFrame2RHeight - 0.5 * sin(detTilt) * (topFrameBotWidth - topFrame2Width) -
0299              siFrSuppBoxYPos[i] - sin(detTilt) * sideFrameRWidth;
0300     }
0301     //position it;
0302     mother.placeVolume(siFrSuppBox,
0303                        isStereo ? 2 : 1,
0304                        dd4hep::Transform3D(
0305                            ns.rotation(waferRot),
0306                            dd4hep::Position(zpos + rPos, isStereo ? xpos + rPos * sin(posCorrectionPhi) : xpos, ypos)));
0307   }
0308 
0309   //The Hybrid
0310   name = idName + "Hybrid";
0311   double dx = 0.5 * hybridWidth;
0312   double dy = 0.5 * hybridThick;
0313   dz = 0.5 * hybridHeight;
0314   solid = Box(dx, dy, dz);
0315   ns.addSolidNS(ns.prepend(name), solid);
0316   edm::LogVerbatim("TECGeom") << "Solid:\t" << name << " " << solid.name() << " Box made of " << hybridMat
0317                               << " of dimensions " << dx << ", " << dy << ", " << dz;
0318   Volume hybrid(ns.prepend(name), solid, ns.material(hybridMat));
0319   ns.addVolumeNS(hybrid);
0320 
0321   ypos = hybridZ;
0322   zpos = 0.5 * (-waferPosition + fullHeight + hybridHeight) + pitchHeight;
0323   if (isRing6)
0324     zpos *= -1;
0325   //position it
0326   mother.placeVolume(
0327       hybrid,
0328       isStereo ? 2 : 1,
0329       dd4hep::Transform3D(ns.rotation(standardRot),
0330                           dd4hep::Position(zpos + rPos, isStereo ? rPos * sin(posCorrectionPhi) : 0., ypos)));
0331 
0332   // Wafer
0333   name = idName + tag + "Wafer";
0334   bl1 = 0.5 * dlBottom;
0335   bl2 = 0.5 * dlTop;
0336   h1 = 0.5 * waferThick;
0337   dz = 0.5 * fullHeight;
0338   solid = Trap(dz, 0, 0, h1, bl1, bl1, 0, h1, bl2, bl2, 0);
0339   ns.addSolidNS(ns.prepend(name), solid);
0340   edm::LogVerbatim("TECGeom") << "Solid:\t" << name << " " << solid.name() << " Trap made of " << waferMat
0341                               << " of dimensions " << dz << ", 0, 0, " << h1 << ", " << bl1 << ", " << bl1 << ", 0, "
0342                               << h1 << ", " << bl2 << ", " << bl2 << ", 0";
0343   Volume wafer(name, solid, ns.material(waferMat));
0344 
0345   ypos = activeZ;
0346   zpos = -0.5 * waferPosition;  // former and incorrect topFrameHeight;
0347   if (isRing6)
0348     zpos *= -1;
0349 
0350   mother.placeVolume(
0351       wafer,
0352       isStereo ? 2 : 1,
0353       dd4hep::Transform3D(ns.rotation(waferRot),
0354                           dd4hep::Position(zpos + rPos, isStereo ? rPos * sin(posCorrectionPhi) : 0., ypos)));
0355 
0356   // Active
0357   name = idName + tag + "Active";
0358   bl1 -= sideWidthBottom;
0359   bl2 -= sideWidthTop;
0360   dz = 0.5 * (waferThick - backplaneThick);  // inactive backplane
0361   h1 = 0.5 * activeHeight;
0362   if (isRing6) {  //switch bl1 <->bl2
0363     tmp = bl2;
0364     bl2 = bl1;
0365     bl1 = tmp;
0366   }
0367   solid = Trap(dz, 0, 0, h1, bl2, bl1, 0, h1, bl2, bl1, 0);
0368   ns.addSolidNS(ns.prepend(name), solid);
0369   edm::LogVerbatim("TECGeom") << "Solid:\t" << name << " " << solid.name() << " Trap made of " << activeMat
0370                               << " of dimensions " << dz << ", 0, 0, " << h1 << ", " << bl2 << ", " << bl1 << ", 0, "
0371                               << h1 << ", " << bl2 << ", " << bl1 << ", 0";
0372   Volume active(ns.prepend(name), solid, ns.material(activeMat));
0373   ns.addVolumeNS(active);
0374 
0375   wafer.placeVolume(
0376       active, 1, dd4hep::Transform3D(ns.rotation(activeRot), dd4hep::Position(0., -0.5 * backplaneThick, 0.)));
0377 
0378   //inactive part in rings > 3
0379   if (ringNo > 3) {
0380     inactivePos -= fullHeight - activeHeight;  //inactivePos is measured from the beginning of the _wafer_
0381     name = idName + tag + "Inactive";
0382     bl1 = 0.5 * dlBottom - sideWidthBottom +
0383           ((0.5 * dlTop - sideWidthTop - 0.5 * dlBottom + sideWidthBottom) / activeHeight) *
0384               (activeHeight - inactivePos - inactiveDy);
0385     bl2 = 0.5 * dlBottom - sideWidthBottom +
0386           ((0.5 * dlTop - sideWidthTop - 0.5 * dlBottom + sideWidthBottom) / activeHeight) *
0387               (activeHeight - inactivePos + inactiveDy);
0388     dz = 0.5 * (waferThick - backplaneThick);  // inactive backplane
0389     h1 = inactiveDy;
0390     if (isRing6) {  //switch bl1 <->bl2
0391       tmp = bl2;
0392       bl2 = bl1;
0393       bl1 = tmp;
0394     }
0395     solid = Trap(dz, 0, 0, h1, bl2, bl1, 0, h1, bl2, bl1, 0);
0396     ns.addSolidNS(ns.prepend(name), solid);
0397     edm::LogVerbatim("TECGeom") << "Solid:\t" << name << " " << solid.name() << " Trap made of " << inactiveMat
0398                                 << " of dimensions " << dz << ", 0, 0, " << h1 << ", " << bl2 << ", " << bl1 << ", 0, "
0399                                 << h1 << ", " << bl2 << ", " << bl1 << ", 0";
0400     Volume inactive(ns.prepend(name), solid, ns.material(inactiveMat));
0401     ns.addVolumeNS(inactive);
0402     ypos = inactivePos - 0.5 * activeHeight;
0403 
0404     active.placeVolume(inactive, 1, dd4hep::Position(0., ypos, 0.));
0405   }
0406   //Pitch Adapter
0407   name = idName + "PA";
0408   name = ns.prepend(name);
0409   if (!isStereo) {
0410     dx = 0.5 * pitchWidth;
0411     dy = 0.5 * pitchThick;
0412     dz = 0.5 * pitchHeight;
0413     solid = Box(dx, dy, dz);
0414     ns.addSolidNS(name, solid);
0415     edm::LogVerbatim("TECGeom") << "Solid:\t" << name << " " << solid.name() << " Box made of " << pitchMat
0416                                 << " of dimensions " << dx << ", " << dy << ", " << dz;
0417   } else {
0418     dz = 0.5 * pitchWidth;
0419     h1 = 0.5 * pitchThick;
0420     bl1 = 0.5 * pitchHeight + 0.5 * dz * sin(detTilt);
0421     bl2 = 0.5 * pitchHeight - 0.5 * dz * sin(detTilt);
0422     thet = atan((bl1 - bl2) / (2. * dz));
0423     solid = Trap(dz, thet, 0, h1, bl1, bl1, 0, h1, bl2, bl2, 0);
0424     ns.addSolidNS(name, solid);
0425     edm::LogVerbatim("TECGeom") << "Solid:\t" << name << " " << solid.name() << " Trap made of " << pitchMat
0426                                 << " of dimensions " << dz << ", " << convertRadToDeg(thet) << ", 0, " << h1 << ", "
0427                                 << bl1 << ", " << bl1 << ", 0, " << h1 << ", " << bl2 << ", " << bl2 << ", 0";
0428   }
0429   xpos = 0;
0430   ypos = pitchZ;
0431   zpos = 0.5 * (-waferPosition + fullHeight + pitchHeight);
0432   if (isRing6)
0433     zpos *= -1;
0434   if (isStereo)
0435     xpos = 0.5 * fullHeight * sin(detTilt);
0436 
0437   Volume pa(name, solid, ns.material(pitchMat));
0438   if (isStereo)
0439     mother.placeVolume(pa,
0440                        2,
0441                        dd4hep::Transform3D(ns.rotation(pitchRot),
0442                                            dd4hep::Position(zpos + rPos, xpos + rPos * sin(posCorrectionPhi), ypos)));
0443   else
0444     mother.placeVolume(pa, 1, dd4hep::Transform3D(ns.rotation(standardRot), dd4hep::Position(zpos + rPos, xpos, ypos)));
0445 
0446   //Top of the frame
0447   name = idName + "TopFrame";
0448   h1 = 0.5 * topFrameThick;
0449   dz = 0.5 * topFrameHeight;
0450   bl1 = 0.5 * topFrameBotWidth;
0451   bl2 = 0.5 * topFrameTopWidth;
0452   if (isRing6) {  // ring 6 faces the other way!
0453     bl1 = 0.5 * topFrameTopWidth;
0454     bl2 = 0.5 * topFrameBotWidth;
0455   }
0456 
0457   solid = Trap(dz, 0, 0, h1, bl1, bl1, 0, h1, bl2, bl2, 0);
0458   ns.addSolid(ns.prepend(name), solid);
0459   edm::LogVerbatim("TECGeom") << "Solid:\t" << name << " " << solid.name() << " Trap made of " << topFrameMat
0460                               << " of dimensions " << dz << ", 0, 0, " << h1 << ", " << bl1 << ", " << bl1 << ", 0, "
0461                               << h1 << ", " << bl2 << ", " << bl2 << ", 0";
0462   Volume topFrame(ns.prepend(name), solid, ns.material(topFrameMat));
0463   ns.addVolumeNS(topFrame);
0464 
0465   if (isStereo) {
0466     name = idName + "TopFrame2";
0467     //additional object to build the not trapzoid geometry of the stereo topframes
0468     dz = 0.5 * topFrame2Width;
0469     h1 = 0.5 * topFrameThick;
0470     bl1 = 0.5 * topFrame2LHeight;
0471     bl2 = 0.5 * topFrame2RHeight;
0472     thet = atan((bl1 - bl2) / (2. * dz));
0473 
0474     constexpr double minDimension = 5.e-8;  // mm value == 5.e-11 meters
0475     if (bl2 < minDimension) {
0476       // If Trapezoid dimension is too tiny, reset to reasonable minimum value that is still effectively zero.
0477       bl2 = minDimension;
0478     }
0479     solid = Trap(dz, thet, 0, h1, bl1, bl1, 0, h1, bl2, bl2, 0);
0480     ns.addSolid(ns.prepend(name), solid);
0481     edm::LogVerbatim("TECGeom") << "Solid:\t" << name << " " << solid.name() << " Trap made of " << topFrameMat
0482                                 << " of dimensions " << dz << ", " << convertRadToDeg(thet) << ", 0, " << h1 << ", "
0483                                 << bl1 << ", " << bl1 << ", 0, " << h1 << ", " << bl2 << ", " << bl2 << ", 0";
0484   }
0485 
0486   // Position the topframe
0487   ypos = topFrameZ;
0488   zpos = 0.5 * (-waferPosition + fullHeight - topFrameHeight) + pitchHeight + hybridHeight;
0489   if (isRing6) {
0490     zpos *= -1;
0491   }
0492 
0493   mother.placeVolume(
0494       topFrame,
0495       isStereo ? 2 : 1,
0496       dd4hep::Transform3D(ns.rotation(standardRot),
0497                           dd4hep::Position(zpos + rPos, isStereo ? rPos * sin(posCorrectionPhi) : 0., ypos)));
0498   if (isStereo) {
0499     //create
0500     Volume topFrame2(name, solid, ns.material(topFrameMat));
0501     zpos -= 0.5 * (topFrameHeight + 0.5 * (topFrame2LHeight + topFrame2RHeight));
0502     mother.placeVolume(
0503         topFrame2,
0504         2,
0505         dd4hep::Transform3D(ns.rotation(pitchRot), dd4hep::Position(zpos + rPos, rPos * sin(posCorrectionPhi), ypos)));
0506   }
0507 
0508   //Si - Reencorcement
0509   matter = ns.material(siReenforceMat);
0510   for (int i = 0; i < (int)(siReenforceWidth.size()); i++) {
0511     name = idName + "SiReenforce" + std::to_string(i);
0512     h1 = 0.5 * siReenforceThick;
0513     dz = 0.5 * siReenforceHeight[i];
0514     bl1 = bl2 = 0.5 * siReenforceWidth[i];
0515     solid = Trap(dz, 0, 0, h1, bl1, bl1, 0, h1, bl2, bl2, 0);
0516     ns.addSolid(ns.prepend(name), solid);
0517     edm::LogVerbatim("TECGeom") << "Solid:\t" << name << " " << solid.name() << " Trap made of " << matter.name()
0518                                 << " of dimensions " << dz << ", 0, 0, " << h1 << ", " << bl1 << ", " << bl1 << ", 0, "
0519                                 << h1 << ", " << bl2 << ", " << bl2 << ", 0";
0520     Volume siReenforce(ns.prepend(name), solid, matter);
0521     ns.addVolumeNS(siReenforce);
0522     //translate
0523     xpos = 0;
0524     ypos = sideFrameZ;
0525     zpos = topFrameEndZ - dz - siReenforceYPos[i];
0526 
0527     if (isRing6)
0528       zpos *= -1;
0529     if (isStereo) {
0530       xpos = (-siReenforceYPos[i] + 0.5 * fullHeight) * sin(detTilt);
0531       //  thet = detTilt;
0532       //  if(topFrame2RHeight > topFrame2LHeight) thet *= -1;
0533       //    zpos -= topFrame2RHeight + sin(thet)*(sideFrameRWidth + 0.5*dlTop);
0534       zpos -= topFrame2RHeight + sin(fabs(detTilt)) * 0.5 * topFrame2Width;
0535     }
0536 
0537     mother.placeVolume(siReenforce,
0538                        isStereo ? 2 : 1,
0539                        dd4hep::Transform3D(
0540                            ns.rotation(waferRot),
0541                            dd4hep::Position(zpos + rPos, isStereo ? xpos + rPos * sin(posCorrectionPhi) : xpos, ypos)));
0542   }
0543 
0544   //Bridge
0545   if (bridgeMat != "None") {
0546     name = idName + "Bridge";
0547     bl2 = 0.5 * bridgeSep + bridgeWidth;
0548     bl1 = bl2 - bridgeHeight * dxdif / dzdif;
0549     h1 = 0.5 * bridgeThick;
0550     dz = 0.5 * bridgeHeight;
0551     solid = Trap(dz, 0, 0, h1, bl1, bl1, 0, h1, bl2, bl2, 0);
0552     ns.addSolid(ns.prepend(name), solid);
0553     edm::LogVerbatim("TECGeom") << "Solid:\t" << name << " " << solid.name() << " Trap made of " << bridgeMat
0554                                 << " of dimensions " << dz << ", 0, 0, " << h1 << ", " << bl1 << ", " << bl1 << ", 0, "
0555                                 << h1 << ", " << bl2 << ", " << bl2 << ", 0";
0556     Volume bridge(ns.prepend(name), solid, ns.material(bridgeMat));
0557     ns.addVolumeNS(bridge);
0558 
0559     name = idName + "BridgeGap";
0560     bl1 = 0.5 * bridgeSep;
0561     solid = Box(bl1, h1, dz);
0562     ns.addSolid(ns.prepend(name), solid);
0563     edm::LogVerbatim("TECGeom") << "Solid:\t" << name << " " << solid.name() << " Box made of " << genMat
0564                                 << " of dimensions " << bl1 << ", " << h1 << ", " << dz;
0565     Volume bridgeGap(ns.prepend(name), solid, ns.material(genMat));
0566     ns.addVolumeNS(bridgeGap);
0567     /* PlacedVolume pv = */ bridge.placeVolume(bridgeGap, 1);
0568     edm::LogVerbatim("TECGeom") << "Solid: " << bridgeGap.name() << " number 1 positioned in " << bridge.name()
0569                                 << " at (0,0,0) with no rotation";
0570   }
0571   edm::LogVerbatim("TECGeom") << "<<== End of DDTECModuleAlgo construction ...";
0572   return 1;
0573 }
0574 
0575 // first argument is the type from the xml file
0576 DECLARE_DDCMS_DETELEMENT(DDCMS_track_DDTECModuleAlgo, algorithm)