Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-05-10 02:20:54

0001 ///////////////////////////////////////////////////////////////////////////////
0002 // File: DDTECModuleAlgo    .cc
0003 // Description: Creation of a TEC Test
0004 ///////////////////////////////////////////////////////////////////////////////
0005 
0006 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0007 #include "DetectorDescription/Core/interface/DDLogicalPart.h"
0008 #include "DetectorDescription/Core/interface/DDSolid.h"
0009 #include "DetectorDescription/Core/interface/DDMaterial.h"
0010 #include "DetectorDescription/Core/interface/DDCurrentNamespace.h"
0011 #include "DetectorDescription/Core/interface/DDSplit.h"
0012 #include "DetectorDescription/Core/interface/DDTypes.h"
0013 #include "DetectorDescription/Core/interface/DDAlgorithm.h"
0014 #include "DetectorDescription/Core/interface/DDAlgorithmFactory.h"
0015 #include <CLHEP/Units/GlobalPhysicalConstants.h>
0016 #include <CLHEP/Units/SystemOfUnits.h>
0017 
0018 #include <cmath>
0019 #include <algorithm>
0020 #include <cstdio>
0021 #include <string>
0022 #include <utility>
0023 #include <map>
0024 #include <string>
0025 #include <vector>
0026 
0027 using namespace std;
0028 
0029 class DDTECModuleAlgo : public DDAlgorithm {
0030 public:
0031   //Constructor and Destructor
0032   DDTECModuleAlgo();
0033   ~DDTECModuleAlgo() override;
0034 
0035   void initialize(const DDNumericArguments& nArgs,
0036                   const DDVectorArguments& vArgs,
0037                   const DDMapArguments& mArgs,
0038                   const DDStringArguments& sArgs,
0039                   const DDStringVectorArguments& vsArgs) override;
0040 
0041   void execute(DDCompactView& cpv) override;
0042 
0043 private:
0044   //this positions  toPos in mother
0045   void doPos(const DDLogicalPart& toPos,
0046              const DDLogicalPart& mother,
0047              int copyNr,
0048              double x,
0049              double y,
0050              double z,
0051              const string& rotName,
0052              DDCompactView& cpv);
0053   void doPos(DDLogicalPart toPos, double x, double y, double z, string rotName, DDCompactView& cpv);
0054   //variables:
0055   double noOverlapShift;
0056   int ringNo;
0057   bool isStereo;
0058   bool isRing6;
0059   double rPos;                       //Position in R relativ to the center of the TEC ( this is the coord-sys of Tubs)
0060   double posCorrectionPhi;           // the Phi position of the stereo Modules has to be corrected
0061   string standardRot;                //Rotation that aligns the mother(Tub ) coordinate System with the components
0062   string idNameSpace;                //Namespace of this and ALL parts
0063   string genMat;                     //General material name
0064   double moduleThick;                //Module thickness
0065   double detTilt;                    //Tilt of stereo detector
0066   double fullHeight;                 //Height
0067   double dlTop;                      //Width at top of wafer
0068   double dlBottom;                   //Width at bottom of wafer
0069   double dlHybrid;                   //Width at the hybrid end
0070   double frameWidth;                 //Frame         width
0071   double frameThick;                 //              thickness
0072   double frameOver;                  //              overlap (on sides)
0073   string topFrameMat;                //Top frame     material
0074   double topFrameHeight;             //              height
0075   double topFrameThick;              //              thickness
0076   double topFrameTopWidth;           //             Width at the top
0077   double topFrameBotWidth;           //             Width at the bottom
0078   double topFrame2Width;             //  Stereo:2ndPart   Width
0079   double topFrame2LHeight;           //             left  height
0080   double topFrame2RHeight;           //             right height
0081   double topFrameZ;                  //              z-positions
0082   string sideFrameMat;               //Side frame    material
0083   double sideFrameThick;             //              thickness
0084   double sideFrameLWidth;            //    Left     Width (for stereo modules upper one)
0085   double sideFrameLWidthLow;         //           Width (only for stereo modules: lower Width)
0086   double sideFrameLHeight;           //             Height
0087   double sideFrameLtheta;            //              angle of the trapezoid shift
0088   double sideFrameRWidth;            //    Right    Width (for stereo modules upper one)
0089   double sideFrameRWidthLow;         //           Width (only for stereo modules: lower Width)
0090   double sideFrameRHeight;           //             Height
0091   double sideFrameRtheta;            //              angle of the trapezoid shift
0092   vector<double> siFrSuppBoxWidth;   //    Supp.Box Width
0093   vector<double> siFrSuppBoxHeight;  //            Height
0094   vector<double> siFrSuppBoxYPos;    //              y-position of the supplies box (with HV an thermal sensor...)
0095   double sideFrameZ;                 //              z-positions
0096   double siFrSuppBoxThick;           //             thickness
0097   string siFrSuppBoxMat;             //              material
0098   string waferMat;                   //Wafer         material
0099   double waferPosition;              //              position of the wafer (was formaly done by adjusting topFrameHeigt)
0100   double sideWidthTop;               //              widths on the side Top
0101   double sideWidthBottom;            //                                 Bottom
0102   string waferRot;                   //              rotation matrix
0103   string activeMat;                  //Sensitive     material
0104   double activeHeight;               //              height
0105   double waferThick;                 //              wafer thickness (active = wafer - backplane)
0106   string activeRot;                  //              Rotation matrix
0107   double activeZ;                    //              z-positions
0108   double backplaneThick;             //              thickness
0109   double inactiveDy;                 //InactiveStrip  Hight of ( rings > 3)
0110   double inactivePos;                //               y-Position
0111   string inactiveMat;                //               material
0112   string hybridMat;                  //Hybrid        material
0113   double hybridHeight;               //              height
0114   double hybridWidth;                //              width
0115   double hybridThick;                //              thickness
0116   double hybridZ;                    //              z-positions
0117   string pitchMat;                   //Pitch adapter material
0118   double pitchWidth;                 //              width
0119   double pitchHeight;                //              height
0120   double pitchThick;                 //              thickness
0121   double pitchZ;                     //              z-positions
0122   string pitchRot;                   //              rotation matrix
0123   string bridgeMat;                  //Bridge        material
0124   double bridgeWidth;                //              width
0125   double bridgeThick;                //              thickness
0126   double bridgeHeight;               //              height
0127   double bridgeSep;                  //              separation
0128   vector<double> siReenforceHeight;  // SiReenforcement Height
0129   vector<double> siReenforceWidth;   //             Width
0130   vector<double> siReenforceYPos;    //              Y - Position
0131   //  double                   siReenforceZPos;//              Z - Position done by the side frames Z Position an t
0132   double siReenforceThick;  //             Thick
0133   string siReenforceMat;    //             Materieal
0134   //double                   posCorrectionR;  //  Correct Positions of the Stereo Modules radial coordinate
0135 };
0136 
0137 DDTECModuleAlgo::DDTECModuleAlgo() { LogDebug("TECGeom") << "DDTECModuleAlgo info: Creating an instance"; }
0138 
0139 DDTECModuleAlgo::~DDTECModuleAlgo() {}
0140 
0141 void DDTECModuleAlgo::initialize(const DDNumericArguments& nArgs,
0142                                  const DDVectorArguments& vArgs,
0143                                  const DDMapArguments&,
0144                                  const DDStringArguments& sArgs,
0145                                  const DDStringVectorArguments& vsArgs) {
0146   idNameSpace = DDCurrentNamespace::ns();
0147   genMat = sArgs["GeneralMaterial"];
0148 
0149   DDName parentName = parent().name();
0150 
0151   LogDebug("TECGeom") << "DDTECModuleAlgo debug: Parent " << parentName << " NameSpace " << idNameSpace
0152                       << " General Material " << genMat;
0153   ringNo = (int)nArgs["RingNo"];
0154   moduleThick = nArgs["ModuleThick"];
0155   detTilt = nArgs["DetTilt"];
0156   fullHeight = nArgs["FullHeight"];
0157   dlTop = nArgs["DlTop"];
0158   dlBottom = nArgs["DlBottom"];
0159   dlHybrid = nArgs["DlHybrid"];
0160   rPos = nArgs["RPos"];
0161   standardRot = sArgs["StandardRotation"];
0162 
0163   isRing6 = (ringNo == 6);
0164 
0165   LogDebug("TECGeom") << "DDTECModuleAlgo debug: ModuleThick " << moduleThick << " Detector Tilt "
0166                       << detTilt / CLHEP::deg << " Height " << fullHeight << " dl(Top) " << dlTop << " dl(Bottom) "
0167                       << dlBottom << " dl(Hybrid) " << dlHybrid << " rPos " << rPos << " standrad rotation "
0168                       << standardRot;
0169 
0170   frameWidth = nArgs["FrameWidth"];
0171   frameThick = nArgs["FrameThick"];
0172   frameOver = nArgs["FrameOver"];
0173   LogDebug("TECGeom") << "DDTECModuleAlgo debug: Frame Width " << frameWidth << " Thickness " << frameThick
0174                       << " Overlap " << frameOver;
0175 
0176   topFrameMat = sArgs["TopFrameMaterial"];
0177   topFrameHeight = nArgs["TopFrameHeight"];
0178   topFrameTopWidth = nArgs["TopFrameTopWidth"];
0179   topFrameBotWidth = nArgs["TopFrameBotWidth"];
0180   topFrameThick = nArgs["TopFrameThick"];
0181   topFrameZ = nArgs["TopFrameZ"];
0182   LogDebug("TECGeom") << "DDTECModuleAlgo debug: Top Frame Material " << topFrameMat << " Height " << topFrameHeight
0183                       << " Top Width " << topFrameTopWidth << " Bottom Width " << topFrameTopWidth << " Thickness "
0184                       << topFrameThick << " positioned at" << topFrameZ;
0185   double resizeH = 0.96;
0186   sideFrameMat = sArgs["SideFrameMaterial"];
0187   sideFrameThick = nArgs["SideFrameThick"];
0188   sideFrameLWidth = nArgs["SideFrameLWidth"];
0189   sideFrameLHeight = resizeH * nArgs["SideFrameLHeight"];
0190   sideFrameLtheta = nArgs["SideFrameLtheta"];
0191   sideFrameRWidth = nArgs["SideFrameRWidth"];
0192   sideFrameRHeight = resizeH * nArgs["SideFrameRHeight"];
0193   sideFrameRtheta = nArgs["SideFrameRtheta"];
0194   siFrSuppBoxWidth = vArgs["SiFrSuppBoxWidth"];
0195   siFrSuppBoxHeight = vArgs["SiFrSuppBoxHeight"];
0196   siFrSuppBoxYPos = vArgs["SiFrSuppBoxYPos"];
0197   siFrSuppBoxThick = nArgs["SiFrSuppBoxThick"];
0198   siFrSuppBoxMat = sArgs["SiFrSuppBoxMaterial"];
0199   sideFrameZ = nArgs["SideFrameZ"];
0200   LogDebug("TECGeom") << "DDTECModuleAlgo debug : Side Frame Material " << sideFrameMat << " Thickness "
0201                       << sideFrameThick << " left Leg's Width: " << sideFrameLWidth
0202                       << " left Leg's Height: " << sideFrameLHeight << " left Leg's tilt(theta): " << sideFrameLtheta
0203                       << " right Leg's Width: " << sideFrameRWidth << " right Leg's Height: " << sideFrameRHeight
0204                       << " right Leg's tilt(theta): " << sideFrameRtheta
0205                       << "Supplies Box's Material: " << siFrSuppBoxMat << " positioned at" << sideFrameZ;
0206   for (int i = 0; i < (int)(siFrSuppBoxWidth.size()); i++) {
0207     LogDebug("TECGeom") << " Supplies Box" << i << "'s Width: " << siFrSuppBoxWidth[i] << " Supplies Box" << i
0208                         << "'s Height: " << siFrSuppBoxHeight[i] << " Supplies Box" << i
0209                         << "'s y Position: " << siFrSuppBoxYPos[i];
0210   }
0211   waferMat = sArgs["WaferMaterial"];
0212   sideWidthTop = nArgs["SideWidthTop"];
0213   sideWidthBottom = nArgs["SideWidthBottom"];
0214   waferRot = sArgs["WaferRotation"];
0215   waferPosition = nArgs["WaferPosition"];
0216   LogDebug("TECGeom") << "DDTECModuleAlgo debug: Wafer Material " << waferMat << " Side Width Top" << sideWidthTop
0217                       << " Side Width Bottom" << sideWidthBottom << " and positioned at " << waferPosition
0218                       << " positioned with rotation"
0219                       << " matrix:" << waferRot;
0220 
0221   activeMat = sArgs["ActiveMaterial"];
0222   activeHeight = nArgs["ActiveHeight"];
0223   waferThick = nArgs["WaferThick"];
0224   activeRot = sArgs["ActiveRotation"];
0225   activeZ = nArgs["ActiveZ"];
0226   backplaneThick = nArgs["BackPlaneThick"];
0227   LogDebug("TECGeom") << "DDTECModuleAlgo debug: Active Material " << activeMat << " Height " << activeHeight
0228                       << " rotated by " << activeRot << " translated by (0,0," << -0.5 * backplaneThick << ")"
0229                       << " Thickness/Z" << waferThick - backplaneThick << "/" << activeZ;
0230 
0231   hybridMat = sArgs["HybridMaterial"];
0232   hybridHeight = nArgs["HybridHeight"];
0233   hybridWidth = nArgs["HybridWidth"];
0234   hybridThick = nArgs["HybridThick"];
0235   hybridZ = nArgs["HybridZ"];
0236   LogDebug("TECGeom") << "DDTECModuleAlgo debug: Hybrid Material " << hybridMat << " Height " << hybridHeight
0237                       << " Width " << hybridWidth << " Thickness " << hybridThick << " Z" << hybridZ;
0238 
0239   pitchMat = sArgs["PitchMaterial"];
0240   pitchHeight = nArgs["PitchHeight"];
0241   pitchThick = nArgs["PitchThick"];
0242   pitchWidth = nArgs["PitchWidth"];
0243   pitchZ = nArgs["PitchZ"];
0244   pitchRot = sArgs["PitchRotation"];
0245   LogDebug("TECGeom") << "DDTECModuleAlgo debug: Pitch Adapter Material " << pitchMat << " Height " << pitchHeight
0246                       << " Thickness " << pitchThick << " position with "
0247                       << " rotation " << pitchRot << " at Z" << pitchZ;
0248 
0249   bridgeMat = sArgs["BridgeMaterial"];
0250   bridgeWidth = nArgs["BridgeWidth"];
0251   bridgeThick = nArgs["BridgeThick"];
0252   bridgeHeight = nArgs["BridgeHeight"];
0253   bridgeSep = nArgs["BridgeSeparation"];
0254   LogDebug("TECGeom") << "DDTECModuleAlgo debug: Bridge Material " << bridgeMat << " Width " << bridgeWidth
0255                       << " Thickness " << bridgeThick << " Height " << bridgeHeight << " Separation " << bridgeSep;
0256 
0257   siReenforceWidth = vArgs["SiReenforcementWidth"];
0258   siReenforceHeight = vArgs["SiReenforcementHeight"];
0259   siReenforceYPos = vArgs["SiReenforcementPosY"];
0260   siReenforceThick = nArgs["SiReenforcementThick"];
0261   siReenforceMat = sArgs["SiReenforcementMaterial"];
0262 
0263   LogDebug("TECGeom") << "FALTBOOT DDTECModuleAlgo debug : Si-Reenforcement Material " << sideFrameMat << " Thickness "
0264                       << siReenforceThick;
0265 
0266   for (int i = 0; i < (int)(siReenforceWidth.size()); i++) {
0267     LogDebug("TECGeom") << " SiReenforcement" << i << "'s Width: " << siReenforceWidth[i] << " SiReenforcement" << i
0268                         << "'s Height: " << siReenforceHeight[i] << " SiReenforcement" << i
0269                         << "'s y Position: " << siReenforceYPos[i];
0270   }
0271   inactiveDy = 0;
0272   inactivePos = 0;
0273   if (ringNo > 3) {
0274     inactiveDy = nArgs["InactiveDy"];
0275     inactivePos = nArgs["InactivePos"];
0276     inactiveMat = sArgs["InactiveMaterial"];
0277   }
0278 
0279   noOverlapShift = nArgs["NoOverlapShift"];
0280   //Everything that is normal/stereo specific comes here
0281   isStereo = (int)nArgs["isStereo"] == 1;
0282   if (!isStereo) {
0283     LogDebug("TECGeom") << "This is a normal module, in ring " << ringNo << "!";
0284   } else {
0285     LogDebug("TECGeom") << "This is a stereo module, in ring " << ringNo << "!";
0286     posCorrectionPhi = nArgs["PosCorrectionPhi"];
0287     topFrame2LHeight = nArgs["TopFrame2LHeight"];
0288     topFrame2RHeight = nArgs["TopFrame2RHeight"];
0289     topFrame2Width = nArgs["TopFrame2Width"];
0290     LogDebug("TECGeom") << "Phi Position corrected by " << posCorrectionPhi << "*rad";
0291     LogDebug("TECGeom") << "DDTECModuleAlgo debug: stereo Top Frame 2nd Part left Heigt " << topFrame2LHeight
0292                         << " right Height " << topFrame2RHeight << " Width " << topFrame2Width;
0293 
0294     sideFrameLWidthLow = nArgs["SideFrameLWidthLow"];
0295     sideFrameRWidthLow = nArgs["SideFrameRWidthLow"];
0296 
0297     LogDebug("TECGeom") << " left Leg's lower Width: " << sideFrameLWidthLow
0298                         << " right Leg's lower Width: " << sideFrameRWidthLow;
0299 
0300     // posCorrectionR =  nArgs["PosCorrectionR"];
0301     //LogDebug("TECGeom") << "Stereo Module Position Correction with R = " << posCorrectionR;
0302   }
0303 }
0304 
0305 void DDTECModuleAlgo::doPos(const DDLogicalPart& toPos,
0306                             const DDLogicalPart& mother,
0307                             int copyNr,
0308                             double x,
0309                             double y,
0310                             double z,
0311                             const string& rotName,
0312                             DDCompactView& cpv) {
0313   DDTranslation tran(z, x, y);
0314   DDRotation rot;
0315   string rotstr = DDSplit(rotName).first;
0316   string rotns;
0317   if (rotstr != "NULL") {
0318     rotns = DDSplit(rotName).second;
0319     rot = DDRotation(DDName(rotstr, rotns));
0320   } else {
0321     rot = DDRotation();
0322   }
0323 
0324   cpv.position(toPos, mother, copyNr, tran, rot);
0325   LogDebug("TECGeom") << "DDTECModuleAlgo test: " << toPos.name() << " positioned in " << mother.name() << " at "
0326                       << tran << " with " << rot;
0327 }
0328 
0329 void DDTECModuleAlgo::doPos(DDLogicalPart toPos, double x, double y, double z, string rotName, DDCompactView& cpv) {
0330   int copyNr = 1;
0331   if (isStereo)
0332     copyNr = 2;
0333 
0334   // This has to be done so that the Mother coordinate System of a Tub resembles
0335   // the coordinate System of a Trap or Box.
0336   z += rPos;
0337 
0338   if (isStereo) {
0339     // z is x , x is y
0340     //z+= rPos*sin(posCorrectionPhi);  <<- this is already corrected with the r position!
0341     x += rPos * sin(posCorrectionPhi);
0342   }
0343   if (rotName == "NULL")
0344     rotName = standardRot;
0345 
0346   doPos(toPos, parent(), copyNr, x, y, z, rotName, cpv);
0347 }
0348 
0349 void DDTECModuleAlgo::execute(DDCompactView& cpv) {
0350   LogDebug("TECGeom") << "==>> Constructing DDTECModuleAlgo...";
0351   //declarations
0352   double tmp;
0353   double dxdif, dzdif;
0354   double dxbot, dxtop;  // topfr;
0355   //positions
0356   double xpos, ypos, zpos;
0357   //dimensons
0358   double bl1, bl2;
0359   double h1;
0360   double dx, dy, dz;
0361   double thet;
0362   //names
0363   string idName;
0364   string name;
0365   string tag("Rphi");
0366   if (isStereo)
0367     tag = "Stereo";
0368   //usefull constants
0369   const double topFrameEndZ = 0.5 * (-waferPosition + fullHeight) + pitchHeight + hybridHeight - topFrameHeight;
0370   DDName parentName = parent().name();
0371   idName = parentName.name();
0372   LogDebug("TECGeom") << "==>> " << idName << " parent " << parentName << " namespace " << idNameSpace;
0373   DDSolid solid;
0374 
0375   //set global parameters
0376   DDName matname(DDSplit(genMat).first, DDSplit(genMat).second);
0377   DDMaterial matter(matname);
0378   dzdif = fullHeight + topFrameHeight;
0379   if (isStereo)
0380     dzdif += 0.5 * (topFrame2LHeight + topFrame2RHeight);
0381 
0382   dxbot = 0.5 * dlBottom + frameWidth - frameOver;
0383   dxtop = 0.5 * dlHybrid + frameWidth - frameOver;
0384   //  topfr = 0.5*dlBottom * sin(detTilt);
0385   if (isRing6) {
0386     dxbot = dxtop;
0387     dxtop = 0.5 * dlTop + frameWidth - frameOver;
0388     //    topfr = 0.5*dlTop    * sin(detTilt);
0389   }
0390   dxdif = dxtop - dxbot;
0391 
0392   //Frame Sides
0393   // left Frame
0394   name = idName + "SideFrameLeft";
0395   matname = DDName(DDSplit(sideFrameMat).first, DDSplit(sideFrameMat).second);
0396   matter = DDMaterial(matname);
0397 
0398   h1 = 0.5 * sideFrameThick;
0399   dz = 0.5 * sideFrameLHeight;
0400   bl1 = bl2 = 0.5 * sideFrameLWidth;
0401   thet = sideFrameLtheta;
0402   //for stereo modules
0403   if (isStereo)
0404     bl1 = 0.5 * sideFrameLWidthLow;
0405   solid = DDSolidFactory::trap(DDName(name, idNameSpace), dz, thet, 0, h1, bl1, bl1, 0, h1, bl2, bl2, 0);
0406   LogDebug("TECGeom") << "DDTECModuleAlgo test:\t" << solid.name() << " Trap made of " << matname << " of dimensions "
0407                       << dz << ",  " << thet << ", 0, " << h1 << ", " << bl1 << ", " << bl1 << ", 0, " << h1 << ", "
0408                       << bl2 << ", " << bl2 << ", 0";
0409   DDLogicalPart sideFrameLeft(solid.ddname(), matter, solid);
0410   //translate
0411   xpos = -0.5 * topFrameBotWidth + bl2 + tan(fabs(thet)) * dz;
0412   ypos = sideFrameZ;
0413   zpos = topFrameEndZ - dz;
0414   //flip ring 6
0415   if (isRing6) {
0416     zpos *= -1;
0417     xpos -= 2 * tan(fabs(thet)) * dz;  // because of the flip the tan(..) to be in the other direction
0418   }
0419   //the stereo modules are on the back of the normal ones...
0420   if (isStereo) {
0421     xpos = -0.5 * topFrameBotWidth + bl2 * cos(detTilt) + dz * sin(fabs(thet) + detTilt) / cos(fabs(thet));
0422     xpos = -xpos;
0423     zpos = topFrameEndZ - topFrame2LHeight - 0.5 * sin(detTilt) * (topFrameBotWidth - topFrame2Width) -
0424            dz * cos(detTilt + fabs(thet)) / cos(fabs(thet)) + bl2 * sin(detTilt) - 0.1 * CLHEP::mm;
0425   }
0426   //position
0427   doPos(sideFrameLeft, xpos, ypos, zpos, waferRot, cpv);
0428 
0429   //right Frame
0430   name = idName + "SideFrameRight";
0431   matname = DDName(DDSplit(sideFrameMat).first, DDSplit(sideFrameMat).second);
0432   matter = DDMaterial(matname);
0433 
0434   h1 = 0.5 * sideFrameThick;
0435   dz = 0.5 * sideFrameRHeight;
0436   bl1 = bl2 = 0.5 * sideFrameRWidth;
0437   thet = sideFrameRtheta;
0438   if (isStereo)
0439     bl1 = 0.5 * sideFrameRWidthLow;
0440   solid = DDSolidFactory::trap(DDName(name, idNameSpace), dz, thet, 0, h1, bl1, bl1, 0, h1, bl2, bl2, 0);
0441   LogDebug("TECGeom") << "DDTECModuleAlgo test:\t" << solid.name() << " Trap made of " << matname << " of dimensions "
0442                       << dz << ", " << thet << ", 0, " << h1 << ", " << bl1 << ", " << bl1 << ", 0, " << h1 << ", "
0443                       << bl2 << ", " << bl2 << ", 0";
0444   DDLogicalPart sideFrameRight(solid.ddname(), matter, solid);
0445   //translate
0446   xpos = 0.5 * topFrameBotWidth - bl2 - tan(fabs(thet)) * dz;
0447   ypos = sideFrameZ;
0448   zpos = topFrameEndZ - dz;
0449   if (isRing6) {
0450     zpos *= -1;
0451     xpos += 2 * tan(fabs(thet)) * dz;  // because of the flip the tan(..) has to be in the other direction
0452   }
0453   if (isStereo) {
0454     xpos = 0.5 * topFrameBotWidth - bl2 * cos(detTilt) - dz * sin(fabs(detTilt - fabs(thet))) / cos(fabs(thet));
0455     xpos = -xpos;
0456     zpos = topFrameEndZ - topFrame2RHeight + 0.5 * sin(detTilt) * (topFrameBotWidth - topFrame2Width) -
0457            dz * cos(detTilt - fabs(thet)) / cos(fabs(thet)) - bl2 * sin(detTilt) - 0.1 * CLHEP::mm;
0458   }
0459   //position it
0460   doPos(sideFrameRight, xpos, ypos, zpos, waferRot, cpv);
0461 
0462   //Supplies Box(es)
0463   for (int i = 0; i < (int)(siFrSuppBoxWidth.size()); i++) {
0464     name = idName + "SuppliesBox" + to_string(i);
0465     matname = DDName(DDSplit(siFrSuppBoxMat).first, DDSplit(siFrSuppBoxMat).second);
0466     matter = DDMaterial(matname);
0467 
0468     h1 = 0.5 * siFrSuppBoxThick;
0469     dz = 0.5 * siFrSuppBoxHeight[i];
0470     bl1 = bl2 = 0.5 * siFrSuppBoxWidth[i];
0471     thet = sideFrameRtheta;
0472     if (isStereo)
0473       thet = -atan(fabs(sideFrameRWidthLow - sideFrameRWidth) / (2 * sideFrameRHeight) - tan(fabs(thet)));
0474     // ^-- this calculates the lower left angel of the tipped trapezoid, which is the SideFframe...
0475 
0476     solid = DDSolidFactory::trap(DDName(name, idNameSpace), dz, thet, 0, h1, bl1, bl1, 0, h1, bl2, bl2, 0);
0477     LogDebug("TECGeom") << "DDTECModuleAlgo test:\t" << solid.name() << " Trap made of " << matname << " of dimensions "
0478                         << dz << ", 0, 0, " << h1 << ", " << bl1 << ", " << bl1 << ", 0, " << h1 << ", " << bl2 << ", "
0479                         << bl2 << ", 0";
0480     DDLogicalPart siFrSuppBox(solid.ddname(), matter, solid);
0481     //translate
0482     xpos = 0.5 * topFrameBotWidth - sideFrameRWidth - bl1 - siFrSuppBoxYPos[i] * tan(fabs(thet));
0483     ypos = sideFrameZ *
0484            (0.5 + (siFrSuppBoxThick / sideFrameThick));  //via * so I do not have to worry about the sign of sideFrameZ
0485     zpos = topFrameEndZ - siFrSuppBoxYPos[i];
0486     if (isRing6) {
0487       xpos += 2 * fabs(tan(thet)) * siFrSuppBoxYPos[i];  // the flipped issue again
0488       zpos *= -1;
0489     }
0490     if (isStereo) {
0491       xpos = 0.5 * topFrameBotWidth - (sideFrameRWidth + bl1) * cos(detTilt) -
0492              sin(fabs(detTilt - fabs(thet))) *
0493                  (siFrSuppBoxYPos[i] + dz * (1 / cos(thet) - cos(detTilt)) + bl1 * sin(detTilt));
0494       xpos = -xpos;
0495       zpos = topFrameEndZ - topFrame2RHeight - 0.5 * sin(detTilt) * (topFrameBotWidth - topFrame2Width) -
0496              siFrSuppBoxYPos[i] - sin(detTilt) * sideFrameRWidth;
0497     }
0498     //position it;
0499     doPos(siFrSuppBox, xpos, ypos, zpos, waferRot, cpv);
0500   }
0501   //The Hybrid
0502   name = idName + "Hybrid";
0503   matname = DDName(DDSplit(hybridMat).first, DDSplit(hybridMat).second);
0504   matter = DDMaterial(matname);
0505   dx = 0.5 * hybridWidth;
0506   dy = 0.5 * hybridThick;
0507   dz = 0.5 * hybridHeight;
0508   solid = DDSolidFactory::box(DDName(name, idNameSpace), dx, dy, dz);
0509   LogDebug("TECGeom") << "DDTECModuleAlgo test:\t" << solid.name() << " Box made of " << matname << " of dimensions "
0510                       << dx << ", " << dy << ", " << dz;
0511   DDLogicalPart hybrid(solid.ddname(), matter, solid);
0512 
0513   ypos = hybridZ;
0514   zpos = 0.5 * (-waferPosition + fullHeight + hybridHeight) + pitchHeight;
0515   if (isRing6)
0516     zpos *= -1;
0517   //position it
0518   doPos(hybrid, 0, ypos, zpos, "NULL", cpv);
0519 
0520   // Wafer
0521   name = idName + tag + "Wafer";
0522   matname = DDName(DDSplit(waferMat).first, DDSplit(waferMat).second);
0523   matter = DDMaterial(matname);
0524   bl1 = 0.5 * dlBottom;
0525   bl2 = 0.5 * dlTop;
0526   h1 = 0.5 * waferThick;
0527   dz = 0.5 * fullHeight;
0528   solid = DDSolidFactory::trap(DDName(name, idNameSpace), dz, 0, 0, h1, bl1, bl1, 0, h1, bl2, bl2, 0);
0529   LogDebug("TECGeom") << "DDTECModuleAlgo test:\t" << solid.name() << " Trap made of " << matname << " of dimensions "
0530                       << dz << ", 0, 0, " << h1 << ", " << bl1 << ", " << bl1 << ", 0, " << h1 << ", " << bl2 << ", "
0531                       << bl2 << ", 0";
0532   DDLogicalPart wafer(solid.ddname(), matter, solid);
0533 
0534   ypos = activeZ;
0535   zpos = -0.5 * waferPosition;  // former and incorrect topFrameHeight;
0536   if (isRing6)
0537     zpos *= -1;
0538 
0539   doPos(wafer, 0, ypos, zpos, waferRot, cpv);
0540 
0541   // Active
0542   name = idName + tag + "Active";
0543   matname = DDName(DDSplit(activeMat).first, DDSplit(activeMat).second);
0544   matter = DDMaterial(matname);
0545   bl1 -= sideWidthBottom;
0546   bl2 -= sideWidthTop;
0547   dz = 0.5 * (waferThick - backplaneThick);  // inactive backplane
0548   h1 = 0.5 * activeHeight;
0549   if (isRing6) {  //switch bl1 <->bl2
0550     tmp = bl2;
0551     bl2 = bl1;
0552     bl1 = tmp;
0553   }
0554   solid = DDSolidFactory::trap(DDName(name, idNameSpace), dz, 0, 0, h1, bl2, bl1, 0, h1, bl2, bl1, 0);
0555   LogDebug("TECGeom") << "DDTECModuleAlgo test:\t" << solid.name() << " Trap made of " << matname << " of dimensions "
0556                       << dz << ", 0, 0, " << h1 << ", " << bl2 << ", " << bl1 << ", 0, " << h1 << ", " << bl2 << ", "
0557                       << bl1 << ", 0";
0558   DDLogicalPart active(solid.ddname(), matter, solid);
0559   doPos(active,
0560         wafer,
0561         1,
0562         -0.5 * backplaneThick,
0563         0,
0564         0,
0565         activeRot,
0566         cpv);  // from the definition of the wafer local axes and doPos() routine
0567   //inactive part in rings > 3
0568   if (ringNo > 3) {
0569     inactivePos -= fullHeight - activeHeight;  //inactivePos is measured from the beginning of the _wafer_
0570     name = idName + tag + "Inactive";
0571     matname = DDName(DDSplit(inactiveMat).first, DDSplit(inactiveMat).second);
0572     matter = DDMaterial(matname);
0573     bl1 = 0.5 * dlBottom - sideWidthBottom +
0574           ((0.5 * dlTop - sideWidthTop - 0.5 * dlBottom + sideWidthBottom) / activeHeight) *
0575               (activeHeight - inactivePos - inactiveDy);
0576     bl2 = 0.5 * dlBottom - sideWidthBottom +
0577           ((0.5 * dlTop - sideWidthTop - 0.5 * dlBottom + sideWidthBottom) / activeHeight) *
0578               (activeHeight - inactivePos + inactiveDy);
0579     dz = 0.5 * (waferThick - backplaneThick);  // inactive backplane
0580     h1 = inactiveDy;
0581     if (isRing6) {  //switch bl1 <->bl2
0582       tmp = bl2;
0583       bl2 = bl1;
0584       bl1 = tmp;
0585     }
0586     solid = DDSolidFactory::trap(DDName(name, idNameSpace), dz, 0, 0, h1, bl2, bl1, 0, h1, bl2, bl1, 0);
0587     LogDebug("TECGeom") << "DDTECModuleAlgo test:\t" << solid.name() << " Trap made of " << matname << " of dimensions "
0588                         << dz << ", 0, 0, " << h1 << ", " << bl2 << ", " << bl1 << ", 0, " << h1 << ", " << bl2 << ", "
0589                         << bl1 << ", 0";
0590     DDLogicalPart inactive(solid.ddname(), matter, solid);
0591     ypos = inactivePos - 0.5 * activeHeight;
0592     doPos(
0593         inactive, active, 1, ypos, 0, 0, "NULL", cpv);  // from the definition of the wafer local axes and doPos() routine
0594   }
0595   //Pitch Adapter
0596   name = idName + "PA";
0597   matname = DDName(DDSplit(pitchMat).first, DDSplit(pitchMat).second);
0598   matter = DDMaterial(matname);
0599 
0600   if (!isStereo) {
0601     dx = 0.5 * pitchWidth;
0602     dy = 0.5 * pitchThick;
0603     dz = 0.5 * pitchHeight;
0604     solid = DDSolidFactory::box(DDName(name, idNameSpace), dx, dy, dz);
0605     LogDebug("TECGeom") << "DDTECModuleAlgo test:\t" << solid.name() << " Box made of " << matname << " of dimensions "
0606                         << dx << ", " << dy << ", " << dz;
0607   } else {
0608     dz = 0.5 * pitchWidth;
0609     h1 = 0.5 * pitchThick;
0610     bl1 = 0.5 * pitchHeight + 0.5 * dz * sin(detTilt);
0611     bl2 = 0.5 * pitchHeight - 0.5 * dz * sin(detTilt);
0612     double thet = atan((bl1 - bl2) / (2. * dz));
0613     solid = DDSolidFactory::trap(DDName(name, idNameSpace), dz, thet, 0, h1, bl1, bl1, 0, h1, bl2, bl2, 0);
0614     LogDebug("TECGeom") << "DDTECModuleAlgo test:\t" << solid.name() << " Trap made of " << matname << " of dimensions "
0615                         << dz << ", " << thet / CLHEP::deg << ", 0, " << h1 << ", " << bl1 << ", " << bl1 << ", 0, "
0616                         << h1 << ", " << bl2 << ", " << bl2 << ", 0";
0617   }
0618   xpos = 0;
0619   ypos = pitchZ;
0620   zpos = 0.5 * (-waferPosition + fullHeight + pitchHeight);
0621   if (isRing6)
0622     zpos *= -1;
0623   if (isStereo)
0624     xpos = 0.5 * fullHeight * sin(detTilt);
0625 
0626   DDLogicalPart pa(solid.ddname(), matter, solid);
0627   if (isStereo)
0628     doPos(pa, xpos, ypos, zpos, pitchRot, cpv);
0629   else
0630     doPos(pa, xpos, ypos, zpos, "NULL", cpv);
0631   //Top of the frame
0632   name = idName + "TopFrame";
0633   matname = DDName(DDSplit(topFrameMat).first, DDSplit(topFrameMat).second);
0634   matter = DDMaterial(matname);
0635 
0636   h1 = 0.5 * topFrameThick;
0637   dz = 0.5 * topFrameHeight;
0638   bl1 = 0.5 * topFrameBotWidth;
0639   bl2 = 0.5 * topFrameTopWidth;
0640   if (isRing6) {  // ring 6 faces the other way!
0641     bl1 = 0.5 * topFrameTopWidth;
0642     bl2 = 0.5 * topFrameBotWidth;
0643   }
0644 
0645   solid = DDSolidFactory::trap(DDName(name, idNameSpace), dz, 0, 0, h1, bl1, bl1, 0, h1, bl2, bl2, 0);
0646   LogDebug("TECGeom") << "DDTECModuleAlgo test:\t" << solid.name() << " Trap made of " << matname << " of dimensions "
0647                       << dz << ", 0, 0, " << h1 << ", " << bl1 << ", " << bl1 << ", 0, " << h1 << ", " << bl2 << ", "
0648                       << bl2 << ", 0";
0649   DDLogicalPart topFrame(solid.ddname(), matter, solid);
0650 
0651   if (isStereo) {
0652     name = idName + "TopFrame2";
0653     //additional object to build the not trapzoid geometry of the stereo topframes
0654     dz = 0.5 * topFrame2Width;
0655     h1 = 0.5 * topFrameThick;
0656     bl1 = 0.5 * topFrame2LHeight;
0657     bl2 = 0.5 * topFrame2RHeight;
0658     double thet = atan((bl1 - bl2) / (2. * dz));
0659 
0660     solid = DDSolidFactory::trap(DDName(name, idNameSpace), dz, thet, 0, h1, bl1, bl1, 0, h1, bl2, bl2, 0);
0661     LogDebug("TECGeom") << "DDTECModuleAlgo test:\t" << solid.name() << " Trap made of " << matname << " of dimensions "
0662                         << dz << ", " << thet / CLHEP::deg << ", 0, " << h1 << ", " << bl1 << ", " << bl1 << ", 0, "
0663                         << h1 << ", " << bl2 << ", " << bl2 << ", 0";
0664   }
0665 
0666   // Position the topframe
0667   ypos = topFrameZ;
0668   zpos = 0.5 * (-waferPosition + fullHeight - topFrameHeight) + pitchHeight + hybridHeight;
0669   if (isRing6) {
0670     zpos *= -1;
0671   }
0672 
0673   doPos(topFrame, 0, ypos, zpos, "NULL", cpv);
0674   if (isStereo) {
0675     //create
0676     DDLogicalPart topFrame2(solid.ddname(), matter, solid);
0677     zpos -= 0.5 * (topFrameHeight + 0.5 * (topFrame2LHeight + topFrame2RHeight));
0678     doPos(topFrame2, 0, ypos, zpos, pitchRot, cpv);
0679   }
0680 
0681   //Si - Reencorcement
0682   for (int i = 0; i < (int)(siReenforceWidth.size()); i++) {
0683     name = idName + "SiReenforce" + to_string(i);
0684     matname = DDName(DDSplit(siReenforceMat).first, DDSplit(siReenforceMat).second);
0685     matter = DDMaterial(matname);
0686 
0687     h1 = 0.5 * siReenforceThick;
0688     dz = 0.5 * siReenforceHeight[i];
0689     bl1 = bl2 = 0.5 * siReenforceWidth[i];
0690 
0691     solid = DDSolidFactory::trap(DDName(name, idNameSpace), dz, 0, 0, h1, bl1, bl1, 0, h1, bl2, bl2, 0);
0692     LogDebug("TECGeom") << "DDTECModuleAlgo test:\t" << solid.name() << " Trap made of " << matname << " of dimensions "
0693                         << dz << ", 0, 0, " << h1 << ", " << bl1 << ", " << bl1 << ", 0, " << h1 << ", " << bl2 << ", "
0694                         << bl2 << ", 0";
0695     DDLogicalPart siReenforce(solid.ddname(), matter, solid);
0696     //translate
0697     xpos = 0;
0698     ypos = sideFrameZ;
0699     zpos = topFrameEndZ - dz - siReenforceYPos[i];
0700 
0701     if (isRing6)
0702       zpos *= -1;
0703     if (isStereo) {
0704       xpos = (-siReenforceYPos[i] + 0.5 * fullHeight) * sin(detTilt);
0705       //  thet = detTilt;
0706       //  if(topFrame2RHeight > topFrame2LHeight) thet *= -1;
0707       //    zpos -= topFrame2RHeight + sin(thet)*(sideFrameRWidth + 0.5*dlTop);
0708       zpos -= topFrame2RHeight + sin(fabs(detTilt)) * 0.5 * topFrame2Width;
0709     }
0710     doPos(siReenforce, xpos, ypos, zpos, waferRot, cpv);
0711   }
0712 
0713   //Bridge
0714   if (bridgeMat != "None") {
0715     name = idName + "Bridge";
0716     matname = DDName(DDSplit(bridgeMat).first, DDSplit(bridgeMat).second);
0717     matter = DDMaterial(matname);
0718     bl2 = 0.5 * bridgeSep + bridgeWidth;
0719     bl1 = bl2 - bridgeHeight * dxdif / dzdif;
0720     h1 = 0.5 * bridgeThick;
0721     dz = 0.5 * bridgeHeight;
0722     solid = DDSolidFactory::trap(DDName(name, idNameSpace), dz, 0, 0, h1, bl1, bl1, 0, h1, bl2, bl2, 0);
0723     LogDebug("TECGeom") << "DDTECModuleAlgo test:\t" << solid.name() << " Trap made of " << matname << " of dimensions "
0724                         << dz << ", 0, 0, " << h1 << ", " << bl1 << ", " << bl1 << ", 0, " << h1 << ", " << bl2 << ", "
0725                         << bl2 << ", 0";
0726     DDLogicalPart bridge(solid.ddname(), matter, solid);
0727 
0728     name = idName + "BridgeGap";
0729     matname = DDName(DDSplit(genMat).first, DDSplit(genMat).second);
0730     matter = DDMaterial(matname);
0731     bl1 = 0.5 * bridgeSep;
0732     solid = DDSolidFactory::box(DDName(name, idNameSpace), bl1, h1, dz);
0733     LogDebug("TECGeom") << "DDTECModuleAlgo test:\t" << solid.name() << " Box made of " << matname << " of dimensions "
0734                         << bl1 << ", " << h1 << ", " << dz;
0735     DDLogicalPart bridgeGap(solid.ddname(), matter, solid);
0736     cpv.position(bridgeGap, bridge, 1, DDTranslation(0.0, 0.0, 0.0), DDRotation());
0737     LogDebug("TECGeom") << "DDTECModuleAlgo test: " << bridgeGap.name() << " number 1 positioned in " << bridge.name()
0738                         << " at (0,0,0) with no rotation";
0739   }
0740 
0741   LogDebug("TECGeom") << "<<== End of DDTECModuleAlgo construction ...";
0742 }
0743 
0744 DEFINE_EDM_PLUGIN(DDAlgorithmFactory, DDTECModuleAlgo, "track:DDTECModuleAlgo");