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