File indexing completed on 2024-04-06 12:15:22
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& , cms::DDParsingContext& ctxt, xml_h e) {
0012 cms::DDNamespace ns(ctxt, e, true);
0013 DDAlgoArguments args(ctxt, e);
0014 string mother = args.parentName();
0015 string genMat = args.str("GeneralMaterial");
0016 int detectorN = args.integer("DetectorNumber");
0017 double moduleThick = args.dble("ModuleThick");
0018 double detTilt = args.dble("DetTilt");
0019 double fullHeight = args.dble("FullHeight");
0020 double dlTop = args.dble("DlTop");
0021 double dlBottom = args.dble("DlBottom");
0022 double dlHybrid = args.dble("DlHybrid");
0023 bool doComponents = ::toupper(args.str("DoComponents")[0]) != 'N';
0024
0025 string boxFrameName = args.str("BoxFrameName");
0026 string boxFrameMat = args.str("BoxFrameMaterial");
0027 double boxFrameHeight = args.dble("BoxFrameHeight");
0028 double boxFrameThick = args.dble("BoxFrameThick");
0029 double boxFrameWidth = args.dble("BoxFrameWidth");
0030 double bottomFrameHeight = args.dble("BottomFrameHeight");
0031 double bottomFrameOver = args.dble("BottomFrameOver");
0032 double topFrameHeight = args.dble("TopFrameHeight");
0033 double topFrameOver = args.dble("TopFrameOver");
0034 vector<string> sideFrameName = args.vecStr("SideFrameName");
0035 string sideFrameMat = args.str("SideFrameMaterial");
0036 double sideFrameWidth = args.dble("SideFrameWidth");
0037 double sideFrameThick = args.dble("SideFrameThick");
0038 double sideFrameOver = args.dble("SideFrameOver");
0039 vector<string> holeFrameName = args.vecStr("HoleFrameName");
0040 vector<string> holeFrameRot = args.vecStr("HoleFrameRotation");
0041
0042 vector<string> kaptonName = args.vecStr("KaptonName");
0043 string kaptonMat = args.str("KaptonMaterial");
0044 double kaptonThick = args.dble("KaptonThick");
0045 double kaptonOver = args.dble("KaptonOver");
0046 vector<string> holeKaptonName = args.vecStr("HoleKaptonName");
0047 vector<string> holeKaptonRot = args.vecStr("HoleKaptonRotation");
0048
0049 vector<string> waferName = args.vecStr("WaferName");
0050 string waferMat = args.str("WaferMaterial");
0051 double sideWidthTop = args.dble("SideWidthTop");
0052 double sideWidthBottom = args.dble("SideWidthBottom");
0053 vector<string> activeName = args.vecStr("ActiveName");
0054 string activeMat = args.str("ActiveMaterial");
0055 double activeHeight = args.dble("ActiveHeight");
0056 vector<double> waferThick =
0057 args.vecDble("WaferThick");
0058 string activeRot = args.str("ActiveRotation");
0059 vector<double> backplaneThick = args.vecDble("BackPlaneThick");
0060 string hybridName = args.str("HybridName");
0061 string hybridMat = args.str("HybridMaterial");
0062 double hybridHeight = args.dble("HybridHeight");
0063 double hybridWidth = args.dble("HybridWidth");
0064 double hybridThick = args.dble("HybridThick");
0065 vector<string> pitchName = args.vecStr("PitchName");
0066 string pitchMat = args.str("PitchMaterial");
0067 double pitchHeight = args.dble("PitchHeight");
0068 double pitchThick = args.dble("PitchThick");
0069 double pitchStereoTol = args.dble("PitchStereoTolerance");
0070 string coolName = args.str("CoolInsertName");
0071 string coolMat = args.str("CoolInsertMaterial");
0072 double coolHeight = args.dble("CoolInsertHeight");
0073 double coolThick = args.dble("CoolInsertThick");
0074 double coolWidth = args.dble("CoolInsertWidth");
0075
0076 edm::LogVerbatim("TIDGeom") << "Parent " << mother << " General Material " << genMat << " Detector Planes "
0077 << detectorN;
0078
0079 edm::LogVerbatim("TIDGeom") << "ModuleThick " << moduleThick << " Detector Tilt " << convertRadToDeg(detTilt)
0080 << " Height " << fullHeight << " dl(Top) " << dlTop << " dl(Bottom) " << dlBottom
0081 << " dl(Hybrid) " << dlHybrid << " doComponents " << doComponents;
0082 edm::LogVerbatim("TIDGeom") << "" << boxFrameName << " Material " << boxFrameMat << " Thickness " << boxFrameThick
0083 << " width " << boxFrameWidth << " height " << boxFrameHeight
0084 << " Extra Height at Bottom " << bottomFrameHeight << " Overlap " << bottomFrameOver;
0085
0086 for (int i = 0; i < detectorN; i++)
0087 edm::LogVerbatim("TIDGeom") << sideFrameName[i] << " Material " << sideFrameMat << " Width " << sideFrameWidth
0088 << " Thickness " << sideFrameThick << " Overlap " << sideFrameOver << " Hole "
0089 << holeFrameName[i];
0090
0091 for (int i = 0; i < detectorN; i++)
0092 edm::LogVerbatim("TIDGeom") << kaptonName[i] << " Material " << kaptonMat << " Thickness " << kaptonThick
0093 << " Overlap " << kaptonOver << " Hole " << holeKaptonName[i];
0094
0095 edm::LogVerbatim("TIDGeom") << "Wafer Material " << waferMat << " Side Width Top " << sideWidthTop
0096 << " Side Width Bottom " << sideWidthBottom;
0097 for (int i = 0; i < detectorN; i++)
0098 edm::LogVerbatim("TIDGeom") << "\twaferName[" << i << "] = " << waferName[i];
0099
0100 edm::LogVerbatim("TIDGeom") << "Active Material " << activeMat << " Height " << activeHeight << " rotated by "
0101 << activeRot;
0102 for (int i = 0; i < detectorN; i++)
0103 edm::LogVerbatim("TIDGeom") << " translated by (0," << -0.5 * backplaneThick[i] << ",0)\tactiveName[" << i
0104 << "] = " << activeName[i] << " of thickness " << waferThick[i] - backplaneThick[i];
0105
0106 edm::LogVerbatim("TIDGeom") << "" << hybridName << " Material " << hybridMat << " Height " << hybridHeight
0107 << " Width " << hybridWidth << " Thickness " << hybridThick;
0108 edm::LogVerbatim("TIDGeom") << "Pitch Adapter Material " << pitchMat << " Height " << pitchHeight << " Thickness "
0109 << pitchThick;
0110 for (int i = 0; i < detectorN; i++)
0111 edm::LogVerbatim("TIDGeom") << "\tpitchName[" << i << "] = " << pitchName[i];
0112 edm::LogVerbatim("TIDGeom") << "Cool Element Material " << coolMat << " Height " << coolHeight << " Thickness "
0113 << coolThick << " Width " << coolWidth;
0114
0115 string name = mother;
0116 double sidfr = sideFrameWidth - sideFrameOver;
0117 double botfr;
0118 double topfr;
0119 double kaptonHeight;
0120 if (dlHybrid > dlTop) {
0121
0122 topfr = topFrameHeight - pitchHeight - topFrameOver;
0123 botfr = bottomFrameHeight - bottomFrameOver;
0124 kaptonHeight = fullHeight + botfr;
0125 } else {
0126
0127 topfr = topFrameHeight - topFrameOver;
0128 botfr = bottomFrameHeight - bottomFrameOver - pitchHeight;
0129 kaptonHeight = fullHeight + topfr;
0130 }
0131
0132 double sideFrameHeight = fullHeight + pitchHeight + botfr + topfr;
0133 double kaptonWidth = sidfr + kaptonOver;
0134
0135 double dxbot = 0.5 * dlBottom + sidfr;
0136 double dxtop = 0.5 * dlTop + sidfr;
0137 double dxtopenv, dxbotenv;
0138
0139
0140 if (dlHybrid > dlTop) {
0141
0142 dxtopenv = dxbot + (dxtop - dxbot) * (fullHeight + pitchHeight + topfr + hybridHeight) / fullHeight;
0143 dxbotenv = dxtop - (dxtop - dxbot) * (fullHeight + botfr) / fullHeight;
0144 } else {
0145
0146 dxtopenv = dxbot + (dxtop - dxbot) * (fullHeight + topfr) / fullHeight;
0147 dxbotenv = dxbot;
0148 }
0149 double bl1 = dxbotenv;
0150 double bl2 = dxtopenv;
0151 double h1 = 0.5 * moduleThick;
0152 double dx, dy;
0153 double dz = 0.5 * (boxFrameHeight + sideFrameHeight);
0154
0155 Solid solid = ns.addSolidNS(ns.prepend(name), Trap(dz, 0, 0, h1, bl1, bl1, 0, h1, bl2, bl2, 0));
0156 ns.addVolumeNS(Volume(ns.prepend(name), solid, ns.material(genMat)));
0157 edm::LogVerbatim("TIDGeom") << solid.name() << " Trap made of " << genMat << " of dimensions " << dz << ", 0, 0, "
0158 << h1 << ", " << bl1 << ", " << bl1 << ", 0, " << h1 << ", " << bl2 << ", " << bl2
0159 << ", 0";
0160
0161 if (doComponents) {
0162
0163 name = boxFrameName;
0164 dx = 0.5 * boxFrameWidth;
0165 dy = 0.5 * boxFrameThick;
0166 dz = 0.5 * boxFrameHeight;
0167 solid = ns.addSolidNS(ns.prepend(name), Box(dx, dy, dz));
0168 edm::LogVerbatim("TIDGeom") << solid.name() << " Box made of " << boxFrameMat << " of dimensions " << dx << ", "
0169 << dy << ", " << dz;
0170 ns.addVolumeNS(Volume(ns.prepend(name), solid, ns.material(boxFrameMat)));
0171
0172
0173 name = hybridName;
0174 dx = 0.5 * hybridWidth;
0175 dy = 0.5 * hybridThick;
0176 dz = 0.5 * hybridHeight;
0177 solid = ns.addSolidNS(ns.prepend(name), Box(dx, dy, dz));
0178 edm::LogVerbatim("TIDGeom") << solid.name() << " Box made of " << hybridMat << " of dimensions " << dx << ", " << dy
0179 << ", " << dz;
0180 ns.addVolumeNS(Volume(ns.prepend(name), solid, ns.material(hybridMat)));
0181
0182
0183 name = coolName;
0184 dx = 0.5 * coolWidth;
0185 dy = 0.5 * coolThick;
0186 dz = 0.5 * coolHeight;
0187 solid = ns.addSolidNS(ns.prepend(name), Box(dx, dy, dz));
0188 edm::LogVerbatim("TIDGeom") << solid.name() << " Box made of " << coolMat << " of dimensions " << dx << ", " << dy
0189 << ", " << dz;
0190 ns.addVolumeNS(Volume(ns.prepend(name), solid, ns.material(coolMat)));
0191
0192
0193 for (int k = 0; k < detectorN; k++) {
0194 double bbl1, bbl2;
0195
0196 name = sideFrameName[k];
0197 if (dlHybrid > dlTop) {
0198
0199 bbl1 = dxtop - (dxtop - dxbot) * (fullHeight + botfr) / fullHeight;
0200 bbl2 = dxbot + (dxtop - dxbot) * (fullHeight + pitchHeight + topfr) / fullHeight;
0201 } else {
0202
0203 bbl1 = dxtop - (dxtop - dxbot) * (fullHeight + pitchHeight + botfr) / fullHeight;
0204 bbl2 = dxbot + (dxtop - dxbot) * (fullHeight + topfr) / fullHeight;
0205 }
0206 h1 = 0.5 * sideFrameThick;
0207 dz = 0.5 * sideFrameHeight;
0208 solid = ns.addSolidNS(ns.prepend(name), Trap(dz, 0., 0., h1, bbl1, bbl1, 0., h1, bbl2, bbl2, 0.));
0209 edm::LogVerbatim("TIDGeom") << solid.name() << " Trap made of " << sideFrameMat << " of dimensions " << dz
0210 << ", 0, 0, " << h1 << ", " << bbl1 << ", " << bbl1 << ", 0, " << h1 << ", " << bbl2
0211 << ", " << bbl2 << ", 0";
0212 Volume sideFrame = ns.addVolumeNS(Volume(ns.prepend(name), solid, ns.material(sideFrameMat)));
0213
0214 std::string rotstr, rotns;
0215 Rotation3D rot;
0216
0217
0218 name = holeFrameName[k];
0219 double xpos, zpos;
0220 dz = fullHeight - bottomFrameOver - topFrameOver;
0221 bbl1 = dxbot - sideFrameWidth + bottomFrameOver * (dxtop - dxbot) / fullHeight;
0222 bbl2 = dxtop - sideFrameWidth - topFrameOver * (dxtop - dxbot) / fullHeight;
0223 if (dlHybrid > dlTop) {
0224
0225 zpos = -(topFrameHeight + 0.5 * dz - 0.5 * sideFrameHeight);
0226 } else {
0227
0228 zpos = bottomFrameHeight + 0.5 * dz - 0.5 * sideFrameHeight;
0229 }
0230 dz /= 2.;
0231 solid = ns.addSolidNS(ns.prepend(name), Trap(dz, 0, 0, h1, bbl1, bbl1, 0, h1, bbl2, bbl2, 0));
0232 edm::LogVerbatim("TIDGeom") << solid.name() << " Trap made of " << genMat << " of dimensions " << dz << ", 0, 0, "
0233 << h1 << ", " << bbl1 << ", " << bbl1 << ", 0, " << h1 << ", " << bbl2 << ", " << bbl2
0234 << ", 0";
0235 Volume holeFrame = ns.addVolumeNS(Volume(ns.prepend(name), solid, ns.material(genMat)));
0236
0237 rot = ns.rotation(holeFrameRot[k]);
0238 sideFrame.placeVolume(holeFrame, 1, Transform3D(rot, Position(0e0, 0e0, zpos)));
0239 edm::LogVerbatim("TIDGeom") << holeFrame.name() << " number 1 positioned in " << sideFrame.name() << " at (0,0,"
0240 << zpos << ") with no rotation";
0241
0242
0243 double kaptonExtraHeight = 0;
0244 if (dlHybrid > dlTop) {
0245
0246 bbl1 = dxtop - (dxtop - dxbot) * (fullHeight + botfr) / fullHeight;
0247 if (k == 1) {
0248 kaptonExtraHeight = dlTop * sin(detTilt) - fullHeight * (1 - cos(detTilt));
0249 kaptonExtraHeight = 0.5 * fabs(kaptonExtraHeight);
0250 bbl2 = dxbot + (dxtop - dxbot) * (fullHeight + kaptonExtraHeight) / fullHeight;
0251 } else {
0252 bbl2 = dxtop;
0253 }
0254 } else {
0255
0256 bbl2 = dxbot + (dxtop - dxbot) * (fullHeight + topfr) / fullHeight;
0257 if (k == 1) {
0258 kaptonExtraHeight = dlBottom * sin(detTilt) - fullHeight * (1 - cos(detTilt));
0259 kaptonExtraHeight = 0.5 * fabs(kaptonExtraHeight);
0260 bbl1 = dxtop - (dxtop - dxbot) * (fullHeight + kaptonExtraHeight) / fullHeight;
0261 } else {
0262 bbl1 = dxbot;
0263 }
0264 }
0265 h1 = 0.5 * kaptonThick;
0266 dz = 0.5 * (kaptonHeight + kaptonExtraHeight);
0267
0268
0269 if (k == 1) {
0270
0271 Solid solidUncut =
0272 ns.addSolidNS(ns.prepend(kaptonName[k] + "Uncut"), Trap(dz, 0., 0., h1, bbl1, bbl1, 0., h1, bbl2, bbl2, 0));
0273
0274
0275 dz = (dlHybrid > dlTop) ? 0.5 * dlTop : 0.5 * dlBottom;
0276 h1 = 0.5 * kaptonThick;
0277 bbl1 = fabs(dz * sin(detTilt));
0278 bbl2 = bbl1 * 0.000001;
0279 double thet = atan((bbl1 - bbl2) / (2 * dz));
0280 Solid solidCut =
0281 ns.addSolidNS(ns.prepend(kaptonName[k] + "Cut"), Trap(dz, thet, 0., h1, bbl1, bbl1, 0., h1, bbl2, bbl2, 0));
0282
0283
0284 name = kaptonName[k];
0285 rot = ns.rotation("tidmodpar:9PYX");
0286 xpos = -0.5 * fullHeight * sin(detTilt);
0287 zpos = 0.5 * kaptonHeight - bbl2;
0288 solid = ns.addSolidNS(ns.prepend(name),
0289 SubtractionSolid(solidUncut, solidCut, Transform3D(rot, Position(xpos, 0.0, zpos))));
0290 } else {
0291 name = kaptonName[k];
0292 solid = ns.addSolidNS(ns.prepend(name), Trap(dz, 0., 0., h1, bbl1, bbl1, 0., h1, bbl2, bbl2, 0.));
0293 }
0294
0295 Volume kapton = ns.addVolumeNS(Volume(ns.prepend(name), solid, ns.material(kaptonMat)));
0296 edm::LogVerbatim("TIDGeom") << solid.name() << " SUBTRACTION SOLID Trap made of " << kaptonMat
0297 << " of dimensions " << dz << ", 0, 0, " << h1 << ", " << bbl1 << ", " << bbl1
0298 << ", 0, " << h1 << ", " << bbl2 << ", " << bbl2 << ", 0";
0299
0300
0301 name = holeKaptonName[k];
0302 dz = fullHeight - kaptonOver;
0303 xpos = 0;
0304 if (dlHybrid > dlTop) {
0305
0306 bbl1 = dxbot - kaptonWidth + kaptonOver * (dxtop - dxbot) / fullHeight;
0307 bbl2 = dxtop - kaptonWidth;
0308 zpos = 0.5 * (kaptonHeight - kaptonExtraHeight - dz);
0309 if (k == 1) {
0310 zpos -= 0.5 * kaptonOver * (1 - cos(detTilt));
0311 xpos = -0.5 * kaptonOver * sin(detTilt);
0312 }
0313 } else {
0314
0315 bbl1 = dxbot - kaptonWidth;
0316 bbl2 = dxtop - kaptonWidth - kaptonOver * (dxtop - dxbot) / fullHeight;
0317 zpos = -0.5 * (kaptonHeight - kaptonExtraHeight - dz);
0318 }
0319 dz /= 2.;
0320 solid = ns.addSolidNS(ns.prepend(name), Trap(dz, 0., 0., h1, bbl1, bbl1, 0., h1, bbl2, bbl2, 0.));
0321 edm::LogVerbatim("TIDGeom") << solid.name() << " Trap made of " << genMat << " of dimensions " << dz << ", 0, 0, "
0322 << h1 << ", " << bbl1 << ", " << bbl1 << ", 0, " << h1 << ", " << bbl2 << ", " << bbl2
0323 << ", 0";
0324 Volume holeKapton = ns.addVolumeNS(Volume(ns.prepend(name), solid, ns.material(genMat)));
0325
0326 rot = ns.rotation(holeKaptonRot[k]);
0327 kapton.placeVolume(holeKapton, 1, Transform3D(rot, Position(xpos, 0.0, zpos)));
0328 edm::LogVerbatim("TIDGeom") << holeKapton.name() << " number 1 positioned in " << kapton.name() << " at (0,0,"
0329 << zpos << ") with no rotation";
0330
0331
0332 name = waferName[k];
0333 if (k == 0 && dlHybrid < dlTop) {
0334 bl1 = 0.5 * dlTop;
0335 bl2 = 0.5 * dlBottom;
0336 } else {
0337 bl1 = 0.5 * dlBottom;
0338 bl2 = 0.5 * dlTop;
0339 }
0340 h1 = 0.5 * waferThick[k];
0341 dz = 0.5 * fullHeight;
0342 solid = ns.addSolidNS(ns.prepend(name), Trap(dz, 0, 0, h1, bl1, bl1, 0, h1, bl2, bl2, 0));
0343 edm::LogVerbatim("TIDGeom") << solid.name() << " Trap made of " << waferMat << " of dimensions " << dz
0344 << ", 0, 0, " << h1 << ", " << bl1 << ", " << bl1 << ", 0, " << h1 << ", " << bl2
0345 << ", " << bl2 << ", 0";
0346 Volume wafer = ns.addVolumeNS(Volume(ns.prepend(name), solid, ns.material(waferMat)));
0347
0348
0349 name = activeName[k];
0350 if (k == 0 && dlHybrid < dlTop) {
0351 bl1 -= sideWidthTop;
0352 bl2 -= sideWidthBottom;
0353 } else {
0354 bl1 -= sideWidthBottom;
0355 bl2 -= sideWidthTop;
0356 }
0357 dz = 0.5 * (waferThick[k] - backplaneThick[k]);
0358 h1 = 0.5 * activeHeight;
0359 solid = ns.addSolidNS(ns.prepend(name), Trap(dz, 0, 0, h1, bl2, bl1, 0, h1, bl2, bl1, 0));
0360 edm::LogVerbatim("TIDGeom") << solid.name() << " Trap made of " << activeMat << " of dimensions " << dz
0361 << ", 0, 0, " << h1 << ", " << bl2 << ", " << bl1 << ", 0, " << h1 << ", " << bl2
0362 << ", " << bl1 << ", 0";
0363 Volume active = ns.addVolumeNS(Volume(ns.prepend(name), solid, ns.material(activeMat)));
0364 rot = ns.rotation(activeRot);
0365 Position tran(0.0, -0.5 * backplaneThick[k], 0.0);
0366 wafer.placeVolume(active, 1, Transform3D(rot, tran));
0367 edm::LogVerbatim("TIDGeom") << "DDTIDModuleAlgo test: " << active.name() << " number 1 positioned in "
0368 << wafer.name() << " at " << tran << " with " << rot;
0369
0370
0371 name = pitchName[k];
0372 if (dlHybrid > dlTop) {
0373 dz = 0.5 * dlTop;
0374 } else {
0375 dz = 0.5 * dlBottom;
0376 }
0377 if (k == 0) {
0378 dx = dz;
0379 dy = 0.5 * pitchThick;
0380 dz = 0.5 * pitchHeight;
0381 solid = ns.addSolidNS(ns.prepend(name), Box(dx, dy, dz));
0382 edm::LogVerbatim("TIDGeom") << solid.name() << " Box made of " << pitchMat << " of dimensions"
0383 << " " << dx << ", " << dy << ", " << dz;
0384 } else {
0385 h1 = 0.5 * pitchThick;
0386 bl1 = 0.5 * pitchHeight + 0.5 * dz * sin(detTilt);
0387 bl2 = 0.5 * pitchHeight - 0.5 * dz * sin(detTilt);
0388
0389 dz -= 0.5 * pitchStereoTol;
0390 bl1 -= pitchStereoTol;
0391 bl2 -= pitchStereoTol;
0392
0393 double thet = atan((bl1 - bl2) / (2. * dz));
0394 solid = ns.addSolidNS(ns.prepend(name), Trap(dz, thet, 0, h1, bl1, bl1, 0, h1, bl2, bl2, 0));
0395 edm::LogVerbatim("TIDGeom") << solid.name() << " Trap made of " << pitchMat << " of "
0396 << "dimensions " << dz << ", " << convertRadToDeg(thet) << ", 0, " << h1 << ", "
0397 << bl1 << ", " << bl1 << ", 0, " << h1 << ", " << bl2 << ", " << bl2 << ", 0";
0398 }
0399 ns.addVolumeNS(Volume(ns.prepend(name), solid, ns.material(pitchMat)));
0400 }
0401 }
0402 edm::LogVerbatim("TIDGeom") << "<<== End of DDTIDModuleAlgo construction ...";
0403 return 1;
0404 }
0405
0406
0407 DECLARE_DDCMS_DETELEMENT(DDCMS_track_DDTIDModuleAlgo, algorithm)