Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-09-01 02:45:10

0001 #include "DD4hep/DetFactoryHelper.h"
0002 #include "DataFormats/Math/interface/CMSUnits.h"
0003 #include "DetectorDescription/DDCMS/interface/DDPlugins.h"
0004 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0005 
0006 using namespace std;
0007 using namespace dd4hep;
0008 using namespace cms;
0009 using namespace cms_units::operators;
0010 
0011 static long algorithm(Detector& /* description */, cms::DDParsingContext& ctxt, xml_h e) {
0012   cms::DDNamespace ns(ctxt, e, true);
0013   DDAlgoArguments args(ctxt, e);
0014   string parentName = args.parentName();
0015   int detectorN = args.integer("DetectorNumber");             //Number of detectors
0016   double detTilt = args.dble("DetTilt");                      //Tilt of stereo detector
0017   double fullHeight = args.dble("FullHeight");                //Height
0018   string boxFrameName = args.str("BoxFrameName");             //Top frame Name
0019   double boxFrameHeight = args.dble("BoxFrameHeight");        //          height
0020   double boxFrameWidth = args.dble("BoxFrameWidth");          //          width
0021   double dlTop = args.dble("DlTop");                          //Width at top of wafer
0022   double dlBottom = args.dble("DlBottom");                    //Width at bottom of wafer
0023   double dlHybrid = args.dble("DlHybrid");                    //Width at the hybrid end
0024   vector<double> boxFrameZ = args.vecDble("BoxFrameZ");       //              z-positions
0025   double bottomFrameHeight = args.dble("BottomFrameHeight");  //Bottom of the frame
0026   double bottomFrameOver = args.dble("BottomFrameOver");      //              overlap
0027   double topFrameHeight = args.dble("TopFrameHeight");        //Top    of the frame
0028   double topFrameOver = args.dble("TopFrameOver");            //              overlap
0029 
0030   vector<string> sideFrameName = args.vecStr("SideFrameName");  //Side Frame    name
0031   vector<double> sideFrameZ = args.vecDble("SideFrameZ");       //              z-positions
0032   vector<string> sideFrameRot = args.vecStr(
0033       "SideFrameRotation");  //              rotation matrix (required for correct positiong of the hole in the StereoR)
0034   double sideFrameWidth = args.dble("SideFrameWidth");  //              width
0035   double sideFrameOver = args.dble("SideFrameOver");    //              overlap (wrt wafer)
0036 
0037   vector<string> kaptonName = args.vecStr("KaptonName");  //Kapton Circuit    name
0038   vector<double> kaptonZ = args.vecDble("KaptonZ");       //              z-positions
0039   vector<string> kaptonRot = args.vecStr(
0040       "KaptonRotation");  //              rotation matrix (required for correct positiong of the hole in the StereoR)
0041   vector<string> waferName = args.vecStr("WaferName");            //Wafer         name
0042   vector<double> waferZ = args.vecDble("WaferZ");                 //              z-positions
0043   vector<string> waferRot = args.vecStr("WaferRotation");         //              rotation matrix
0044   string hybridName = args.str("HybridName");                     //Hybrid        name
0045   double hybridHeight = args.dble("HybridHeight");                //              height
0046   vector<double> hybridZ = args.vecDble("HybridZ");               //              z-positions
0047   vector<string> pitchName = args.vecStr("PitchName");            //Pitch adapter rotation matrix
0048   double pitchHeight = args.dble("PitchHeight");                  //              height
0049   vector<double> pitchZ = args.vecDble("PitchZ");                 //              z-positions
0050   vector<string> pitchRot = args.vecStr("PitchRotation");         //              rotation matrix
0051   string coolName = args.str("CoolInsertName");                   //Cool Insert   name
0052   double coolHeight = args.dble("CoolInsertHeight");              //              height
0053   double coolZ = args.dble("CoolInsertZ");                        //              z-position
0054   double coolWidth = args.dble("CoolInsertWidth");                //              width
0055   vector<double> coolRadShift = args.vecDble("CoolInsertShift");  //
0056 
0057   bool doSpacers =
0058       ::toupper(args.str("DoSpacers")[0]) != 'N';  //Spacers (alumina) to be made (Should be "Yes" for DS modules only)
0059   string botSpacersName = args.str("BottomSpacersName");       // Spacers at the "bottom" of the module
0060   double botSpacersHeight = args.dble("BottomSpacersHeight");  //
0061   double botSpacersZ = args.dble("BottomSpacersZ");            //              z-position
0062   string sidSpacersName = args.str("SideSpacersName");         //Spacers at the "sides" of the module
0063   double sidSpacersHeight = args.dble("SideSpacersHeight");
0064   double sidSpacersZ = args.dble("SideSpacersZ");             //              z-position
0065   double sidSpacersWidth = args.dble("SideSpacersWidth");     //              width
0066   double sidSpacersRadShift = args.dble("SideSpacersShift");  //
0067 
0068   edm::LogVerbatim("TIDGeom") << "Parent " << parentName << " Detector Planes " << detectorN;
0069   edm::LogVerbatim("TIDGeom") << "Detector Tilt " << convertRadToDeg(detTilt) << " Height " << fullHeight << " dl(Top) "
0070                               << dlTop << " dl(Bottom) " << dlBottom << " dl(Hybrid) " << dlHybrid;
0071   edm::LogVerbatim("TIDGeom") << boxFrameName << " positioned at Z";
0072   for (int i = 0; i < detectorN; i++)
0073     edm::LogVerbatim("TIDGeom") << "\tboxFrameZ[" << i << "] = " << boxFrameZ[i];
0074   edm::LogVerbatim("TIDGeom") << "\t Extra Height at Bottom " << bottomFrameHeight << " Overlap " << bottomFrameOver;
0075   for (int i = 0; i < detectorN; i++)
0076     edm::LogVerbatim("TIDGeom") << "\tsideFrame[" << i << "] = " << sideFrameName[i] << " positioned at Z "
0077                                 << sideFrameZ[i] << " with rotation " << sideFrameRot[i];
0078   for (int i = 0; i < detectorN; i++)
0079     edm::LogVerbatim("TIDGeom") << "\tkapton[" << i << "] = " << kaptonName[i] << " positioned at Z " << kaptonZ[i]
0080                                 << " with rotation " << kaptonRot[i];
0081   for (int i = 0; i < detectorN; i++)
0082     edm::LogVerbatim("TIDGeom") << waferName[i] << " positioned at Z " << waferZ[i] << " with rotation " << waferRot[i];
0083   edm::LogVerbatim("TIDGeom") << hybridName << " Height " << hybridHeight << " Z";
0084   for (int i = 0; i < detectorN; i++)
0085     edm::LogVerbatim("TIDGeom") << "\thybridZ[" << i << "] = " << hybridZ[i];
0086   edm::LogVerbatim("TIDGeom") << "Pitch Adapter Height " << pitchHeight;
0087   for (int i = 0; i < detectorN; i++)
0088     edm::LogVerbatim("TIDGeom") << pitchName[i] << " position at Z " << pitchZ[i] << " with rotation " << pitchRot[i];
0089 
0090   string name;
0091   double botfr;  // width of side frame at the the bottom of the modules
0092   double topfr;  // width of side frame at the the top of the modules
0093   double kaptonHeight;
0094   if (dlHybrid > dlTop) {
0095     // ring 1, ring 2
0096     topfr = topFrameHeight - pitchHeight - topFrameOver;
0097     botfr = bottomFrameHeight - bottomFrameOver;
0098     kaptonHeight = fullHeight + botfr;
0099   } else {
0100     // ring 3
0101     topfr = topFrameHeight - topFrameOver;
0102     botfr = bottomFrameHeight - bottomFrameOver - pitchHeight;
0103     kaptonHeight = fullHeight + topfr;
0104   }
0105 
0106   double sideFrameHeight = fullHeight + pitchHeight + botfr + topfr;
0107   double zCenter = 0.5 * (sideFrameHeight + boxFrameHeight);
0108 
0109   // (Re) Compute the envelope for positioning Cool Inserts and Side Spacers (Alumina).
0110   double sidfr = sideFrameWidth - sideFrameOver;  // width of side frame on the sides of module
0111   double dxbot = 0.5 * dlBottom + sidfr;
0112   double dxtop = 0.5 * dlTop + sidfr;
0113   double dxtopenv, dxbotenv;  // top/bot width of the module envelope trap
0114 
0115   double tanWafer = (dxtop - dxbot) / fullHeight;  //
0116   double thetaWafer = atan(tanWafer);              // 1/2 of the wafer wedge angle
0117 
0118   if (dlHybrid > dlTop) {
0119     // ring 1, ring 2
0120     dxtopenv = dxbot + (dxtop - dxbot) * (fullHeight + pitchHeight + topfr + hybridHeight) / fullHeight;
0121     dxbotenv = dxtop - (dxtop - dxbot) * (fullHeight + botfr) / fullHeight;
0122   } else {
0123     // ring 3
0124     dxtopenv = dxbot + (dxtop - dxbot) * (fullHeight + topfr) / fullHeight;
0125     dxbotenv = dxbot;
0126   }
0127 
0128   double tanEnv = (dxtopenv - dxbotenv) / (sideFrameHeight + boxFrameHeight);  // 1/2 of the envelope wedge angle
0129 
0130   double xpos = 0;
0131   double ypos = 0;
0132   double zpos = 0;
0133 
0134   // Cool Inserts
0135   name = coolName;
0136   ypos = coolZ;
0137 
0138   double zCool;
0139   int copy = 0;
0140   Rotation3D rot;  // should be different for different elements
0141   Volume parentVol = ns.volume(parentName);
0142 
0143   for (int j1 = 0; j1 < 2; j1++) {  // j1: 0 inserts below the hybrid
0144     //     1 inserts below the wafer
0145     if (dlHybrid > dlTop) {
0146       zCool = sideFrameHeight + boxFrameHeight - coolRadShift[j1];
0147       if (j1 == 0)
0148         zCool -= 0.5 * coolHeight;
0149     } else {
0150       zCool = coolRadShift[j1];
0151       if (j1 == 0)
0152         zCool += 0.5 * coolHeight;
0153     }
0154 
0155     if (j1 == 0) {
0156       xpos = -0.5 * (boxFrameWidth - coolWidth);
0157     } else {
0158       xpos = -(dxbotenv + (zCool - 0.5 * coolHeight) * tanEnv - 0.5 * coolWidth);
0159     }
0160 
0161     zpos = zCool - zCenter;
0162     for (int j2 = 0; j2 < 2; j2++) {
0163       copy++;
0164       parentVol.placeVolume(ns.volume(name), copy, Position(xpos, ypos, zpos));
0165       edm::LogVerbatim("TIDGeom") << name << " number " << copy << " positioned in " << parentName << " at "
0166                                   << Position(xpos, ypos, zpos) << " with " << rot;
0167       xpos = -xpos;
0168     }
0169   }
0170 
0171   if (doSpacers) {
0172     // Bottom Spacers (Alumina)
0173     name = botSpacersName;
0174     ypos = botSpacersZ;
0175     double zBotSpacers;
0176     if (dlHybrid > dlTop) {
0177       zBotSpacers = sideFrameHeight + boxFrameHeight - 0.5 * botSpacersHeight;
0178     } else {
0179       zBotSpacers = 0.5 * botSpacersHeight;
0180     }
0181     zpos = zBotSpacers - zCenter;
0182     parentVol.placeVolume(ns.volume(name), 1, Position(0.0, ypos, zpos));
0183     edm::LogVerbatim("TIDGeom") << name << " number " << 1 << " positioned in " << parentName << " at "
0184                                 << Position(0.0, ypos, zpos) << " with no rotation";
0185     // Side Spacers (Alumina)
0186     name = sidSpacersName;
0187     ypos = sidSpacersZ;
0188     double zSideSpacers;
0189     if (dlHybrid > dlTop) {
0190       zSideSpacers = sideFrameHeight + boxFrameHeight - sidSpacersRadShift;
0191     } else {
0192       zSideSpacers = sidSpacersRadShift;
0193     }
0194     zpos = zSideSpacers - zCenter;
0195 
0196     copy = 0;
0197     xpos = dxbotenv + (zSideSpacers - 0.5 * sidSpacersHeight) * tanEnv - 0.5 * sidSpacersWidth + sideFrameOver;
0198 
0199     double phiy = 0e0, phiz = 0e0;
0200     double phix = 0._deg;
0201     phiy = 90._deg;
0202     phiz = 0._deg;
0203 
0204     double thetax = 0e0;
0205     double thetay = 90._deg;
0206     double thetaz = thetaWafer;
0207 
0208     for (int j1 = 0; j1 < 2; j1++) {
0209       copy++;
0210       // tilt Side Spacers (parallel to Side Frame)
0211       thetax = 90._deg + thetaz;
0212       rot = makeRotation3D(thetax, phix, thetay, phiy, thetaz, phiz);
0213       parentVol.placeVolume(ns.volume(name), copy, Transform3D(rot, Position(xpos, ypos, zpos)));
0214       edm::LogVerbatim("TIDGeom") << name << " number " << copy << " positioned in " << parentName << " at "
0215                                   << Position(xpos, ypos, zpos) << " with " << rot;
0216       xpos = -xpos;
0217       thetaz = -thetaz;
0218     }
0219   }
0220 
0221   // Loop over detectors to be placed
0222   for (int k = 0; k < detectorN; k++) {
0223     // Wafer
0224     name = waferName[k];
0225     xpos = 0;
0226     ypos = waferZ[k];
0227     double zWafer;
0228     if (dlHybrid > dlTop) {
0229       zWafer = botfr + 0.5 * fullHeight;
0230     } else {
0231       zWafer = boxFrameHeight + botfr + pitchHeight + 0.5 * fullHeight;
0232     }
0233     zpos = zWafer - zCenter;
0234     Position tran(xpos, ypos, zpos);
0235     rot = ns.rotation(waferRot[k]);
0236 
0237     parentVol.placeVolume(ns.volume(name), k + 1, Transform3D(rot, tran));  // copyNr=k+1
0238     edm::LogVerbatim("TIDGeom") << name << " number " << k + 1 << " positioned in " << parentName << " at " << tran
0239                                 << " with " << rot;
0240 
0241     //Pitch Adapter
0242     name = pitchName[k];
0243     if (k == 0) {
0244       xpos = 0;
0245     } else {
0246       xpos = 0.5 * fullHeight * sin(detTilt);
0247     }
0248     ypos = pitchZ[k];
0249     double zPitch;
0250     if (dlHybrid > dlTop) {
0251       zPitch = botfr + fullHeight + 0.5 * pitchHeight;
0252     } else {
0253       zPitch = boxFrameHeight + botfr + 0.5 * pitchHeight;
0254     }
0255     zpos = zPitch - zCenter;
0256     rot = ns.rotation(pitchRot[k]);
0257     tran = Position(xpos, ypos, zpos);
0258     parentVol.placeVolume(ns.volume(name), k + 1, Transform3D(rot, tran));  // copyNr=k+1
0259     edm::LogVerbatim("TIDGeom") << name << " number " << k + 1 << " positioned in " << parentName << " at " << tran
0260                                 << " with " << rot;
0261 
0262     // Hybrid
0263     name = hybridName;
0264     ypos = hybridZ[k];
0265     double zHybrid;
0266     if (dlHybrid > dlTop) {
0267       zHybrid = botfr + fullHeight + pitchHeight + 0.5 * hybridHeight;
0268     } else {
0269       zHybrid = 0.5 * hybridHeight;
0270     }
0271     zpos = zHybrid - zCenter;
0272     tran = Position(0, ypos, zpos);
0273     parentVol.placeVolume(ns.volume(name), k + 1, tran);  // copyNr=k+1
0274     edm::LogVerbatim("TIDGeom") << name << " number " << k + 1 << " positioned in " << parentName << " at " << tran;
0275 
0276     // Box frame
0277     name = boxFrameName;
0278     ypos = boxFrameZ[k];
0279     double zBoxFrame;
0280     if (dlHybrid > dlTop) {
0281       zBoxFrame = sideFrameHeight + 0.5 * boxFrameHeight;
0282     } else {
0283       zBoxFrame = 0.5 * boxFrameHeight;
0284     }
0285     zpos = zBoxFrame - zCenter;
0286     tran = Position(0, ypos, zpos);
0287     parentVol.placeVolume(ns.volume(name), k + 1, tran);  // copyNr=k+1
0288     edm::LogVerbatim("TIDGeom") << name << " number " << k + 1 << " positioned in " << parentName << " at " << tran;
0289 
0290     // Side frame
0291     name = sideFrameName[k];
0292     ypos = sideFrameZ[k];
0293     double zSideFrame;
0294     if (dlHybrid > dlTop) {
0295       zSideFrame = 0.5 * sideFrameHeight;
0296     } else {
0297       zSideFrame = boxFrameHeight + 0.5 * sideFrameHeight;
0298     }
0299     zpos = zSideFrame - zCenter;
0300     rot = ns.rotation(sideFrameRot[k]);
0301     tran = Position(0, ypos, zpos);
0302     parentVol.placeVolume(ns.volume(name), k + 1, Transform3D(rot, tran));
0303     edm::LogVerbatim("TIDGeom") << name << " number " << k + 1 << " positioned in " << parentName << " at " << tran
0304                                 << " with " << rot;
0305     // Kapton circuit
0306     name = kaptonName[k];
0307     ypos = kaptonZ[k];
0308     double zKapton;
0309     double kaptonExtraHeight = 0;
0310     if (dlHybrid > dlTop) {
0311       if (k == 1)
0312         kaptonExtraHeight = dlTop * sin(detTilt) - fullHeight * (1 - cos(detTilt));
0313       kaptonExtraHeight = 0.5 * fabs(kaptonExtraHeight);
0314       zKapton = 0.5 * (kaptonHeight + kaptonExtraHeight);
0315     } else {
0316       if (k == 1)
0317         kaptonExtraHeight = dlBottom * sin(detTilt) - fullHeight * (1 - cos(detTilt));
0318       kaptonExtraHeight = 0.5 * fabs(kaptonExtraHeight);
0319       zKapton = boxFrameHeight + sideFrameHeight - 0.5 * (kaptonHeight + kaptonExtraHeight);
0320     }
0321     zpos = zKapton - zCenter;
0322     rot = ns.rotation(kaptonRot[k]);
0323     tran = Position(0, ypos, zpos);
0324     parentVol.placeVolume(ns.volume(name), k + 1, Transform3D(rot, tran));
0325     edm::LogVerbatim("TIDGeom") << name << " number " << k + 1 << " positioned in " << parentName << " at " << tran
0326                                 << " with " << rot;
0327   }
0328   edm::LogVerbatim("TIDGeom") << "<<== End of DDTIDModulePosAlgo positioning ...";
0329   return 1;
0330 }
0331 
0332 // first argument is the type from the xml file
0333 DECLARE_DDCMS_DETELEMENT(DDCMS_track_DDTIDModulePosAlgo, algorithm)