File indexing completed on 2025-12-17 09:22:09
0001 #include "PHG4MvtxSupport.h"
0002
0003 #include "PHG4MvtxCable.h"
0004 #include "PHG4MvtxDetector.h"
0005 #include "PHG4MvtxDisplayAction.h"
0006
0007 #include <g4main/PHG4Detector.h>
0008
0009 #include <Geant4/G4AssemblyVolume.hh>
0010 #include <Geant4/G4Box.hh>
0011 #include <Geant4/G4LogicalVolume.hh>
0012 #include <Geant4/G4Material.hh>
0013 #include <Geant4/G4Polycone.hh>
0014 #include <Geant4/G4RotationMatrix.hh> // for G4RotationMatrix
0015 #include <Geant4/G4String.hh>
0016 #include <Geant4/G4SubtractionSolid.hh>
0017 #include <Geant4/G4SystemOfUnits.hh>
0018 #include <Geant4/G4ThreeVector.hh> // for G4ThreeVector
0019 #include <Geant4/G4Transform3D.hh>
0020 #include <Geant4/G4Tubs.hh>
0021 #include <Geant4/G4Types.hh>
0022 #include <Geant4/G4UserLimits.hh>
0023
0024 #include <algorithm> // for max
0025 #include <cmath> // for M_PI, atan, cos, sin
0026 #include <format>
0027 #include <iostream> // for operator<<, basic_...
0028 #include <regex> // for regex
0029 #include <utility> // for pair, make_pair
0030 #include <vector>
0031
0032 class G4VSolid;
0033
0034 namespace ServiceProperties
0035 {
0036
0037
0038
0039 const double sEndWheelSNHolesZdist = 308.0 * mm;
0040 const double sEndWStepHoleZpos = 4. * mm;
0041 const double sEndWStepHoleZdist = 4. * mm;
0042 const double sEndWheelNLen = 30. * mm;
0043
0044 const double sCYSSFlgSsfFlgNsf = 606.59 * mm;
0045 const double sCYSSFlgSsfCylsf = 181. * mm;
0046 const double sCYSSFlgSsfConesf = 7. * mm;
0047 const double sCYSSFlgSsfRibsf = 50. * mm;
0048 const double sPP2sfSBsf = 791.77 * mm;
0049 const double sPP2Len = 80 * mm;
0050
0051 double ServiceEnd = -7.21 * cm;
0052 double ServiceOffset = -16.0 * cm;
0053 double BarrelOffset = 18.679 * cm;
0054 double BarrelRadius = 10.33 * cm;
0055 double BarrelThickness = 0.436 * cm;
0056 double BarrelLength = 1214.4 * mm;
0057 double BarrelCableStart = sEndWheelSNHolesZdist / 2 - (sEndWStepHoleZpos + sEndWStepHoleZdist) + sEndWheelNLen - sCYSSFlgSsfFlgNsf - BarrelLength + sPP2sfSBsf + sPP2Len / 2;
0058 double BarrelCableEnd = BarrelCableStart - (sPP2sfSBsf + sPP2Len / 2);
0059 double LayerThickness = 0.1 * cm;
0060 double CYSSConeThickness = 0.216 * cm;
0061 double CYSSRibThickness = 0.170 * cm;
0062 double cableRotate[3] = {10., 5., 5.};
0063 }
0064
0065
0066 PHG4MvtxSupport::PHG4MvtxSupport(PHG4MvtxDetector *detector, PHG4MvtxDisplayAction *dispAct, bool overlapCheck)
0067 : m_Detector(detector)
0068 , m_DisplayAction(dispAct)
0069 , m_overlapCheck(overlapCheck)
0070 {
0071 }
0072
0073
0074 PHG4MvtxSupport::~PHG4MvtxSupport()
0075 {
0076 delete m_avSupport;
0077 delete m_avBarrelCable;
0078 for (auto *av : m_avLayerCable)
0079 {
0080 delete av;
0081 }
0082 }
0083
0084
0085 void PHG4MvtxSupport::CreateMvtxSupportMaterials()
0086 {
0087 G4double density;
0088 G4int natoms;
0089 G4String symbol;
0090 G4String material = "MVTX_EW_Al$";
0091 if (!PHG4Detector::GetDetectorMaterial(material, false))
0092 {
0093 auto *MVTX_Al = new G4Material(material, density = 2.7 * g / cm3,
0094 natoms = 1, kStateSolid);
0095 MVTX_Al->AddMaterial(PHG4Detector::GetDetectorMaterial("G4_Al"), 100 * perCent);
0096 }
0097
0098 material = "MVTX_Epoxy$";
0099 if (!PHG4Detector::GetDetectorMaterial(material, false))
0100 {
0101 auto *MVTX_Epoxy = new G4Material(material, density = 1.56 * g / cm3, natoms = 4);
0102 MVTX_Epoxy->AddElement(PHG4Detector::GetDetectorElement("H", true), 32);
0103 MVTX_Epoxy->AddElement(PHG4Detector::GetDetectorElement("C", true), 2);
0104 MVTX_Epoxy->AddElement(PHG4Detector::GetDetectorElement("N", true), 4);
0105 MVTX_Epoxy->AddElement(PHG4Detector::GetDetectorElement("O", true), 15);
0106 }
0107
0108 material = "MVTX_CarbonFiber$";
0109 if (!PHG4Detector::GetDetectorMaterial(material, false))
0110 {
0111 auto *MVTX_CF = new G4Material(material, density = 1.987 * g / cm3,
0112 natoms = 2);
0113 MVTX_CF->AddMaterial(PHG4Detector::GetDetectorMaterial("G4_C"), 70 * perCent);
0114 MVTX_CF->AddMaterial(PHG4Detector::GetDetectorMaterial("MVTX_Epoxy$"), 30 * perCent);
0115 }
0116 }
0117
0118
0119 void PHG4MvtxSupport::CreateEndWheelsSideN(G4AssemblyVolume *&av)
0120 {
0121 for (unsigned int iLay = 0; iLay < PHG4MvtxDefs::kNLayers; iLay++)
0122 {
0123 GetEndWheelSideN(iLay, av);
0124 }
0125 }
0126
0127
0128 void PHG4MvtxSupport::GetEndWheelSideN(const int lay, G4AssemblyVolume *&endWheel)
0129 {
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151 const double sEndWheelNRmax[3] = {30.57 * mm, 38.59 * mm, 46.30 * mm};
0152 const double sEndWheelNRmin[3] = {22.83 * mm, 30.67 * mm, 38.70 * mm};
0153 const double sEndWheelNWallR[3] = {29.57 * mm, 37.59 * mm, 45.30 * mm};
0154 const double sEndWheelNThick = 2.8 * mm;
0155
0156 const int sEndWNBaseNBigHoles = 6;
0157 const int sEndWNBaseNSmallHoles = 5;
0158 const double sEndWNBaseBigHoleD = 4 * mm;
0159 const double sEndWNBaseSmallHoleD = 1.6 * mm;
0160 const double sEndWNBaseHolesR[3] = {27. * mm, 35. * mm, 42.7 * mm};
0161 const double sEndWNBaseHolesPhi = 15.;
0162
0163 const int sEndWNWallNHoles[3] = {6, 8, 10};
0164 const double sEndWNWallHoleD = 4.5 * mm;
0165
0166
0167 const double sEndWNStepXlen[3] = {9.88 * mm, 11.2 * mm, 8.38 * mm};
0168 const double sEndWNStepYdispl[3] = {26.521 * mm, 33.891 * mm, 41.64 * mm};
0169 const double sEndWNStepHolePhi[3] = {30.0, 22.5, 18.0};
0170 const double sEndWNStepHoleTilt[3] = {0., 0.295, 0.297};
0171
0172 const double sEndWNStepZlen = ServiceProperties::sEndWheelNLen - sEndWheelNThick;
0173
0174
0175 double rmin;
0176 double rmax;
0177 double phimin;
0178 double dphi;
0179 double xpos;
0180 double ypos;
0181 double zpos;
0182 double rpos;
0183 double xlen;
0184 double ylen;
0185
0186 auto Ta = G4ThreeVector();
0187 auto Ra = G4RotationMatrix();
0188
0189 const unsigned short nZplanes = 4;
0190 const double zPlane[nZplanes] = {0. * mm,
0191 ServiceProperties::sEndWheelNLen - sEndWheelNThick,
0192 ServiceProperties::sEndWheelNLen - sEndWheelNThick,
0193 ServiceProperties::sEndWheelNLen};
0194
0195 const double rInner[nZplanes] = {sEndWheelNWallR[lay], sEndWheelNWallR[lay],
0196 sEndWheelNRmin[lay], sEndWheelNRmin[lay]};
0197
0198 const double rOuter[nZplanes] = {sEndWheelNRmax[lay], sEndWheelNRmax[lay],
0199 sEndWheelNRmax[lay], sEndWheelNRmax[lay]};
0200
0201 G4VSolid *endWNBasis = new G4Polycone(std::string("endwnbasis" + std::to_string(lay)), 0., 2. * M_PI * rad,
0202 nZplanes, zPlane, rInner, rOuter);
0203
0204
0205 auto *endwnwalhol = new G4Tubs(std::string("endwnwalhol" + std::to_string(lay)), 0, sEndWNWallHoleD / 2,
0206 1.5 * (sEndWheelNRmax[lay] - sEndWheelNWallR[lay]),
0207 0, 2 * M_PI * rad);
0208
0209 rmin = (sEndWheelNRmax[lay] + sEndWheelNWallR[lay]) / 2;
0210 zpos = ServiceProperties::sEndWStepHoleZpos;
0211 dphi = 180. / sEndWNWallNHoles[lay];
0212 phimin = dphi / 2;
0213 for (int ihole = 0; ihole < 2 * sEndWNWallNHoles[lay]; ihole++)
0214 {
0215 double phi = phimin + ihole * dphi;
0216 xpos = rmin * sin(phi * deg);
0217 ypos = rmin * cos(phi * deg);
0218 Ra.set(-phi * deg, 90 * deg, 0.);
0219 Ta.set(xpos, ypos, zpos);
0220 endWNBasis = new G4SubtractionSolid(std::string("endwnbasis-endwnwalhol" + std::to_string(ihole) + "l" + std::to_string(lay)),
0221 endWNBasis, endwnwalhol, &Ra, Ta);
0222 }
0223
0224
0225 auto *endwnbasBhol = new G4Tubs(std::string("endwnbasBhol" + std::to_string(lay)), 0, sEndWNBaseBigHoleD / 2,
0226 1.5 * sEndWheelNThick, 0, 2 * M_PI * rad);
0227
0228 auto *endwnbasShol = new G4Tubs(std::string("endwnbasShol" + std::to_string(lay)), 0, sEndWNBaseSmallHoleD / 2,
0229 1.5 * sEndWheelNThick, 0, 2 * M_PI * rad);
0230
0231 rmin = sEndWNBaseHolesR[lay];
0232 zpos = ServiceProperties::sEndWheelNLen - (sEndWheelNThick / 2);
0233 phimin = 0.;
0234 for (int ihole = 0; ihole < (sEndWNBaseNBigHoles + sEndWNBaseNSmallHoles); ihole++)
0235 {
0236 phimin += sEndWNBaseHolesPhi;
0237 xpos = rmin * cos(phimin * deg);
0238 ypos = rmin * sin(phimin * deg);
0239 Ra.set(0., 0., 0.);
0240 Ta.set(xpos, ypos, zpos);
0241 auto *endwnbashol = (ihole < 2 || ihole == 5 || ihole > 8) ? endwnbasShol : endwnbasBhol;
0242 endWNBasis = new G4SubtractionSolid(std::string("endwnbasis-endwnwalhol" + std::to_string(ihole) + "l" + std::to_string(lay) + "a"),
0243 endWNBasis, endwnbashol, &Ra, Ta);
0244 Ta = G4ThreeVector(-xpos, -ypos, zpos);
0245 endWNBasis = new G4SubtractionSolid(std::string("endwnbasis-endwnwalhol" + std::to_string(ihole) + "l" + std::to_string(lay) + "b"),
0246 endWNBasis, endwnbashol, &Ra, Ta);
0247 }
0248
0249
0250
0251 rmin = sEndWheelNWallR[lay];
0252 xlen = sEndWNStepXlen[lay] - ((lay == 1) ? 0.01 * mm : 0. * mm);
0253 double xDispl = sqrt(rmin * rmin - sEndWNStepYdispl[lay] * sEndWNStepYdispl[lay]) - xlen;
0254 ylen = sqrt(rmin * rmin - xDispl * xDispl) - sEndWNStepYdispl[lay];
0255
0256 auto *stepBoxNSh = new G4Box(std::string("stepBoxNSh" + std::to_string(lay)), xlen / 2, ylen / 2,
0257 (sEndWNStepZlen / 2) - 0.05 * mm);
0258
0259 xpos = xDispl + stepBoxNSh->GetXHalfLength();
0260 ypos = sEndWNStepYdispl[lay] + stepBoxNSh->GetYHalfLength();
0261 rpos = std::sqrt(xpos * xpos + ypos * ypos);
0262
0263 phimin = (90. * deg) - acos(sEndWNStepYdispl[lay] / rmin) * rad - 5 * deg;
0264 dphi = (90. * deg) - asin(xDispl / rmin) * rad - phimin + 5 * deg;
0265 rmax = rmin + 2 * stepBoxNSh->GetYHalfLength();
0266
0267 auto *stepTubNSh = new G4Tubs(std::string("stepTubNSh" + std::to_string(lay)), rmin, rmax,
0268 1.5 * sEndWNStepZlen / 2, phimin, dphi);
0269 Ra.set(0., 0., 0.);
0270 Ta.set(-xpos, -ypos, 0);
0271 auto *stepNSh = new G4SubtractionSolid(std::string("stepNSh" + std::to_string(lay)),
0272 stepBoxNSh, stepTubNSh, &Ra, Ta);
0273
0274 auto *matAl = PHG4Detector::GetDetectorMaterial("MVTX_EW_Al$");
0275
0276 auto *endWheelNvol = new G4LogicalVolume(endWNBasis, matAl, std::string("EndWheelNBasis" + std::to_string(lay)));
0277 m_DisplayAction->AddVolume(endWheelNvol, "red");
0278 m_Detector->FillSupportLVArray(endWheelNvol);
0279
0280 auto *stepNShLogVol = new G4LogicalVolume(stepNSh, matAl, std::string("StepNL" + std::to_string(lay) + "_LOGIC"));
0281 m_DisplayAction->AddVolume(stepNShLogVol, "red");
0282 m_Detector->FillSupportLVArray(stepNShLogVol);
0283
0284
0285 zpos = (ServiceProperties::sEndWheelSNHolesZdist / 2) - (ServiceProperties::sEndWStepHoleZpos + ServiceProperties::sEndWStepHoleZdist);
0286 Ra.set(0., 0., 0.);
0287 Ta.set(0, 0, zpos);
0288 endWheel->AddPlacedVolume(endWheelNvol, Ta, &Ra);
0289
0290 dphi = std::atan(ypos / xpos);
0291 double phi0 = PHG4MvtxDefs::mvtxdat[lay][PHG4MvtxDefs::kPhi0];
0292 const int numberOfStaves = PHG4MvtxDefs::mvtxdat[lay][PHG4MvtxDefs::kNStave];
0293 zpos += (stepBoxNSh->GetZHalfLength());
0294 for (int j = 0; j < numberOfStaves; j++)
0295 {
0296 double phi = phi0 * rad;
0297 phi += j * sEndWNStepHolePhi[lay] * deg;
0298 phi -= sEndWNStepHoleTilt[lay];
0299 xpos = rpos * cos(phi);
0300 ypos = rpos * sin(phi);
0301 Ra.set(0., 0., dphi - phi);
0302 Ta.set(xpos, ypos, zpos);
0303 endWheel->AddPlacedVolume(stepNShLogVol, Ta, &Ra);
0304 }
0305
0306 return;
0307 }
0308
0309
0310 void PHG4MvtxSupport::CreateEndWheelsSideS(G4AssemblyVolume *&av)
0311 {
0312 for (unsigned int iLay = 0; iLay < PHG4MvtxDefs::kNLayers; iLay++)
0313 {
0314 GetEndWheelSideS(iLay, av);
0315 }
0316 }
0317
0318
0319 void PHG4MvtxSupport::GetEndWheelSideS(const int lay, G4AssemblyVolume *&endWheel)
0320 {
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342 const double sEWSExtSectRmax[3] = {30.97 * mm, 38.99 * mm, 46.74 * mm};
0343 const double sEWSExtSectThick[3] = {0.97 * mm, 1.20 * mm, 1.01 * mm};
0344
0345 const double sEWSIntSectRmax[3] = {29.77 * mm, 37.79 * mm, 45.54 * mm};
0346 const double sEWSIntSectRmin[3] = {28.80 * mm, 36.80 * mm, 44.50 * mm};
0347 const double sEWSIntSectLongLen = 26 * mm;
0348 const double sEWSIntSectShortLen = 25 * mm;
0349
0350 const double sEWSTotalLen = 42. * mm;
0351
0352 const int sEndWSWallNHoles[3] = {6, 8, 10};
0353 const double sEndWSWallHoleD = 4.5 * mm;
0354
0355 const double sEndWSStepXlen[3] = {10.80 * mm, 10.05 * mm, 9.45 * mm};
0356 const double sEndWSStepYdispl[3] = {26.52 * mm, 33.89 * mm, 41.64 * mm};
0357 const double sEndWSStepHolePhi[3] = {30.0, 22.5, 18.0};
0358 const double sEndWSStepHoleTilt[3] = {0., 0.295, 0.297};
0359
0360 const double sEndWSStepZlen = sEWSTotalLen - sEWSIntSectLongLen;
0361 const double sEndWheelNWallR = sEWSExtSectRmax[lay] - sEWSExtSectThick[lay] + 0.05 * mm;
0362
0363
0364 double rmin;
0365 double rmax;
0366 double phimin;
0367 double dphi;
0368 double xpos;
0369 double ypos;
0370 double zpos;
0371 double rpos;
0372 double xlen;
0373 double ylen;
0374
0375 auto Ta = G4ThreeVector();
0376 auto Ra = G4RotationMatrix();
0377
0378 const unsigned short nZplanes = 6;
0379 const double zPlane[nZplanes] = {0. * mm,
0380 sEWSTotalLen - sEWSIntSectLongLen,
0381 sEWSTotalLen - sEWSIntSectLongLen,
0382 sEWSTotalLen - sEWSIntSectShortLen,
0383 sEWSTotalLen - sEWSIntSectShortLen,
0384 sEWSTotalLen};
0385
0386 const double rInner[nZplanes] = {sEndWheelNWallR,
0387 sEndWheelNWallR,
0388 sEWSIntSectRmin[lay],
0389 sEWSIntSectRmin[lay],
0390 sEWSIntSectRmin[lay],
0391 sEWSIntSectRmin[lay]};
0392
0393 const double rOuter[nZplanes] = {sEWSExtSectRmax[lay],
0394 sEWSExtSectRmax[lay],
0395 sEWSExtSectRmax[lay],
0396 sEWSExtSectRmax[lay],
0397 sEWSIntSectRmax[lay],
0398 sEWSIntSectRmax[lay]};
0399
0400 G4VSolid *endWSBasis = new G4Polycone(std::string("endwsbasis" + std::to_string(lay)), 0., 2. * M_PI * rad,
0401 nZplanes, zPlane, rInner, rOuter);
0402
0403
0404 auto *endwswalhol = new G4Tubs(std::string("endwswalhol" + std::to_string(lay)), 0, sEndWSWallHoleD / 2,
0405 1.5 * sEWSExtSectThick[lay],
0406 0, 2 * M_PI * rad);
0407
0408 rmin = sEWSExtSectRmax[lay] - sEWSExtSectThick[lay] / 2;
0409 zpos = ServiceProperties::sEndWStepHoleZpos;
0410 dphi = 180. / sEndWSWallNHoles[lay];
0411 phimin = dphi / 2;
0412 for (int ihole = 0; ihole < 2 * sEndWSWallNHoles[lay]; ihole++)
0413 {
0414 double phi = phimin + ihole * dphi;
0415 xpos = rmin * sin(phi * deg);
0416 ypos = rmin * cos(phi * deg);
0417 Ra.set(-phi * deg, 90 * deg, 0);
0418 Ta.set(xpos, ypos, zpos);
0419 endWSBasis = new G4SubtractionSolid(std::string("endwsbasis-endwswalhol" + std::to_string(ihole) + "l" + std::to_string(lay)),
0420 endWSBasis, endwswalhol, &Ra, Ta);
0421 }
0422
0423
0424
0425 rmin = sEWSExtSectRmax[lay] - sEWSExtSectThick[lay];
0426 xlen = sEndWSStepXlen[lay];
0427 double xDispl = sqrt(rmin * rmin - sEndWSStepYdispl[lay] * sEndWSStepYdispl[lay]) - xlen;
0428 ylen = sqrt(rmin * rmin - xDispl * xDispl) - sEndWSStepYdispl[lay];
0429
0430 auto *stepBoxSSh = new G4Box(std::string("stepBoxSSh" + std::to_string(lay)), xlen / 2, ylen / 2,
0431 (sEndWSStepZlen / 2) - 0.05 * mm);
0432
0433 xpos = xDispl + stepBoxSSh->GetXHalfLength();
0434 ypos = sEndWSStepYdispl[lay] + stepBoxSSh->GetYHalfLength();
0435 rpos = std::sqrt(xpos * xpos + ypos * ypos);
0436
0437 phimin = (90. * deg) - acos(sEndWSStepYdispl[lay] / rmin) * rad - 5 * deg;
0438 dphi = (90. * deg) - asin(xDispl / rmin) * rad - phimin + 5 * deg;
0439 rmax = rmin + 2 * stepBoxSSh->GetYHalfLength();
0440
0441 auto *stepTubSSh = new G4Tubs(std::string("stepTubSSh" + std::to_string(lay)), rmin, rmax,
0442 1.5 * sEndWSStepZlen / 2, phimin, dphi);
0443 Ra.set(0., 0., 0.);
0444 Ta.set(-xpos, -ypos, 0.);
0445 auto *stepSSh = new G4SubtractionSolid(std::string("stepSSh" + std::to_string(lay)),
0446 stepBoxSSh, stepTubSSh, &Ra, Ta);
0447
0448 auto *matAl = PHG4Detector::GetDetectorMaterial("MVTX_EW_Al$");
0449
0450 auto *endWheelSvol = new G4LogicalVolume(endWSBasis, matAl, std::string("EndWheelSBasis" + std::to_string(lay)));
0451 m_DisplayAction->AddVolume(endWheelSvol, "red");
0452 m_Detector->FillSupportLVArray(endWheelSvol);
0453
0454 auto *stepSShLogVol = new G4LogicalVolume(stepSSh, matAl, std::string("StepSL" + std::to_string(lay) + "_LOGIC"));
0455 m_DisplayAction->AddVolume(stepSShLogVol, "red");
0456 m_Detector->FillSupportLVArray(stepSShLogVol);
0457
0458
0459 zpos = (ServiceProperties::sEndWheelSNHolesZdist / 2) - (ServiceProperties::sEndWStepHoleZpos + ServiceProperties::sEndWStepHoleZdist);
0460 Ra.set(0., M_PI * rad, 0.);
0461 Ta.set(0, 0, -zpos);
0462 endWheel->AddPlacedVolume(endWheelSvol, Ta, &Ra);
0463
0464 dphi = std::atan(ypos / xpos);
0465 double phi0 = PHG4MvtxDefs::mvtxdat[lay][PHG4MvtxDefs::kPhi0];
0466 const int numberOfStaves = PHG4MvtxDefs::mvtxdat[lay][PHG4MvtxDefs::kNStave];
0467 zpos += (stepBoxSSh->GetZHalfLength());
0468 for (int j = 0; j < numberOfStaves; j++)
0469 {
0470 double phi = phi0 * rad;
0471 phi += j * sEndWSStepHolePhi[lay] * deg;
0472 phi -= sEndWSStepHoleTilt[lay];
0473 xpos = rpos * cos(phi);
0474 ypos = rpos * sin(phi);
0475 Ra.set(0., 0., dphi - phi);
0476 Ta.set(xpos, ypos, -zpos);
0477 endWheel->AddPlacedVolume(stepSShLogVol, Ta, &Ra);
0478 }
0479
0480 return;
0481 }
0482
0483
0484 void PHG4MvtxSupport::CreateConeLayers(G4AssemblyVolume *&av)
0485 {
0486 for (unsigned int iLay = 0; iLay < PHG4MvtxDefs::kNLayers; iLay++)
0487 {
0488 GetConeVolume(iLay, av);
0489 }
0490 }
0491
0492
0493 void PHG4MvtxSupport::GetConeVolume(int lay, G4AssemblyVolume *&av)
0494 {
0495
0496
0497
0498
0499
0500
0501
0502
0503
0504
0505
0506
0507
0508
0509
0510
0511
0512 const double sEndWheelSExtSectLen = 17 * mm;
0513
0514 const double sThickness[3] = {1. * mm, 1.12 * mm, 1.12 * mm};
0515 const double sBigCylDmax[3] = {103 * mm, 149 * mm, 195 * mm};
0516 const double sBigCylDmin = sBigCylDmax[lay] - 2 * sThickness[lay];
0517 const double sSmallCylDmin[3] = {59.94 * mm, 75.98 * mm, 91.48 * mm};
0518 const double sTotalLen[3] = {186.8 * mm, 179.74 * mm, 223 * mm};
0519 const double sSmallCylLen[3] = {91.86 * mm, 89.38 * mm, 85.38 * mm};
0520 const double sConePlusSCLen[3] = {165.79 * mm, 158.51 * mm, 152.06 * mm};
0521
0522 const int nZplanes = 4;
0523 const double zPlane[nZplanes] = {0 * mm,
0524 -sSmallCylLen[lay],
0525 -sConePlusSCLen[lay],
0526 -sTotalLen[lay]};
0527
0528 const double rInner[nZplanes] = {sSmallCylDmin[lay] / 2,
0529 sSmallCylDmin[lay] / 2,
0530 sBigCylDmin / 2,
0531 sBigCylDmin / 2};
0532
0533 const double rOuter[nZplanes] = {sSmallCylDmin[lay] / 2 + sThickness[lay],
0534 sSmallCylDmin[lay] / 2 + sThickness[lay],
0535 sBigCylDmax[lay] / 2,
0536 sBigCylDmax[lay] / 2};
0537
0538 auto *coneSolid = new G4Polycone(std::string("cfConeL" + std::to_string(lay)), 0., 2. * M_PI * rad,
0539 nZplanes, zPlane, rInner, rOuter);
0540
0541 auto *matCF = PHG4Detector::GetDetectorMaterial("MVTX_CarbonFiber$");
0542
0543 auto *coneLogVol = new G4LogicalVolume(coneSolid, matCF,
0544 std::string("ConeL" + std::to_string(lay) + "_LOGIC"),
0545 nullptr, nullptr, nullptr);
0546
0547 m_DisplayAction->AddVolume(coneLogVol, "MVTX_CarbonFiber$");
0548 m_Detector->FillSupportLVArray(coneLogVol);
0549
0550 double zpos = ServiceProperties::sEndWheelSNHolesZdist / 2 - (ServiceProperties::sEndWStepHoleZpos + ServiceProperties::sEndWStepHoleZdist) + sEndWheelSExtSectLen;
0551 G4ThreeVector Ta = G4ThreeVector(0., 0., -zpos);
0552 G4RotationMatrix Ra;
0553 av->AddPlacedVolume(coneLogVol, Ta, &Ra);
0554
0555 return;
0556 }
0557
0558
0559 void PHG4MvtxSupport::CreateCYSS(G4AssemblyVolume *&av)
0560 {
0561
0562
0563
0564
0565
0566
0567
0568
0569
0570
0571
0572
0573
0574
0575
0576
0577
0578
0579
0580
0581
0582
0583
0584 const double sFlgExtThick = 1 * mm;
0585 const double sFlgIntThick = 1.5 * mm;
0586 const double sFlgSringLen = 4.5 * mm;
0587 const double sFlgLringLen = 7.5 * mm;
0588 const double sFlgRmin = 23.6 * mm;
0589 const double sFlgRmax = 52.8 * mm;
0590 const double sFlgSringRmin = 46.4 * mm;
0591 const double sFlgSringRmax = 47.4 * mm;
0592 const double sFlgLringRmin = 50.6 * mm;
0593 const double sFlgLringRmax = 51.5 * mm;
0594
0595 const int nZplanes = 4;
0596 const double zPlane_1[nZplanes] = {0. * mm,
0597 sFlgIntThick,
0598 sFlgIntThick,
0599 sFlgSringLen};
0600
0601 const double rInner_1[nZplanes] = {sFlgRmin,
0602 sFlgRmin,
0603 sFlgSringRmin,
0604 sFlgSringRmin};
0605
0606 const double rOuter_1[nZplanes] = {sFlgLringRmin,
0607 sFlgLringRmin,
0608 sFlgSringRmax,
0609 sFlgSringRmax};
0610
0611 const double zPlane_2[nZplanes] = {0. * mm,
0612 sFlgExtThick,
0613 sFlgExtThick,
0614 sFlgLringLen};
0615
0616 const double rInner_2[nZplanes] = {sFlgLringRmin,
0617 sFlgLringRmin,
0618 sFlgLringRmin,
0619 sFlgLringRmin};
0620
0621 const double rOuter_2[nZplanes] = {sFlgRmax,
0622 sFlgRmax,
0623 sFlgLringRmax,
0624 sFlgLringRmax};
0625
0626 auto *flangeSolid_1 = new G4Polycone("cyssFlangeNorth_1", 0., 2. * M_PI * rad,
0627 nZplanes, zPlane_1, rInner_1, rOuter_1);
0628
0629 auto *flangeSolid_2 = new G4Polycone("cyssFlangeNorth_2", 0., 2. * M_PI * rad,
0630 nZplanes, zPlane_2, rInner_2, rOuter_2);
0631
0632 auto *matAl = PHG4Detector::GetDetectorMaterial("MVTX_EW_Al$");
0633
0634 auto *cyssFlangeLogVol_1 = new G4LogicalVolume(flangeSolid_1, matAl,
0635 "cyssFlangeNorth_1_LOGIC",
0636 nullptr, nullptr, nullptr);
0637
0638 m_DisplayAction->AddVolume(cyssFlangeLogVol_1, "MVTX_EW_Al$");
0639 m_Detector->FillSupportLVArray(cyssFlangeLogVol_1);
0640
0641 auto *cyssFlangeLogVol_2 = new G4LogicalVolume(flangeSolid_2, matAl,
0642 "cyssFlangeNorth_2_LOGIC",
0643 nullptr, nullptr, nullptr);
0644
0645 m_DisplayAction->AddVolume(cyssFlangeLogVol_2, "MVTX_EW_Al$");
0646 m_Detector->FillSupportLVArray(cyssFlangeLogVol_2);
0647
0648 double zpos = ServiceProperties::sEndWheelSNHolesZdist / 2 - (ServiceProperties::sEndWStepHoleZpos + ServiceProperties::sEndWStepHoleZdist) + ServiceProperties::sEndWheelNLen + sFlgIntThick;
0649 G4ThreeVector Ta = G4ThreeVector(0., 0., zpos);
0650 G4RotationMatrix Ra(0, M_PI * rad, 0.);
0651 av->AddPlacedVolume(cyssFlangeLogVol_1, Ta, &Ra);
0652 av->AddPlacedVolume(cyssFlangeLogVol_2, Ta, &Ra);
0653
0654
0655 const double sCYSScylRmax = 52.82 * mm;
0656 const double sCYSScylRmin = 51.70 * mm;
0657 const double sCYSScylLen = 425.77 * mm;
0658
0659 auto *cyssCylSol = new G4Tubs("CYSScyl_SOLID", sCYSScylRmin, sCYSScylRmax, sCYSScylLen / 2,
0660 0., 2 * M_PI);
0661
0662 auto *matCF = PHG4Detector::GetDetectorMaterial("MVTX_CarbonFiber$");
0663 auto *cyssCylLog = new G4LogicalVolume(cyssCylSol, matCF, "CYSScyl_LOGIC",
0664 nullptr, nullptr, nullptr);
0665 m_DisplayAction->AddVolume(cyssCylLog, "MVTX_CarbonFiber$");
0666 m_Detector->FillSupportLVArray(cyssCylLog);
0667
0668 zpos -= (sFlgIntThick - sCYSScylLen / 2 + ServiceProperties::sCYSSFlgSsfFlgNsf - ServiceProperties::sCYSSFlgSsfCylsf);
0669 Ta.set(0., 0., zpos);
0670 Ra.set(0, 0., 0.);
0671 av->AddPlacedVolume(cyssCylLog, Ta, &Ra);
0672
0673
0674 const double sCYSSconFlgDmin = 106.03 * mm;
0675 const double sCYSSconIntDmin = 211.00 * mm;
0676 const double sCYSSconFlgThick = 1.12 * mm;
0677 const double sCYSSconFlgLen = 13.48 * mm;
0678 const double sCYSSconNoseLen = 24.39 * mm;
0679 const double sCYSSconThick = 2.16 * mm;
0680 const double sCYSSconSlopeLen = 95.0 * mm;
0681 const double sCYSSconLen = 200.28 * mm;
0682
0683 const int nZplanesCone = 5;
0684
0685 const double zPlanesCone[nZplanesCone] = {0 * mm,
0686 sCYSSconFlgLen,
0687 sCYSSconNoseLen,
0688 sCYSSconSlopeLen,
0689 sCYSSconLen};
0690
0691 const double rInnerCone[nZplanesCone] = {sCYSSconFlgDmin / 2,
0692 sCYSSconFlgDmin / 2,
0693 sCYSSconFlgDmin / 2,
0694 sCYSSconIntDmin / 2,
0695 sCYSSconIntDmin / 2};
0696
0697 const double rOuterCone[nZplanesCone] = {(sCYSSconFlgDmin + sCYSSconFlgThick) / 2,
0698 (sCYSSconFlgDmin + sCYSSconThick) / 2,
0699 (sCYSSconFlgDmin + sCYSSconThick) / 2,
0700 (sCYSSconIntDmin + sCYSSconThick) / 2,
0701 (sCYSSconIntDmin + sCYSSconThick) / 2};
0702
0703 auto *cyssConeSol = new G4Polycone("cyssConeSol", 0., 2. * M_PI * rad,
0704 nZplanesCone, zPlanesCone, rInnerCone, rOuterCone);
0705
0706 auto *cyssConeLog = new G4LogicalVolume(cyssConeSol, matCF, "CYSScone_LOGIC",
0707 nullptr, nullptr, nullptr);
0708 m_DisplayAction->AddVolume(cyssConeLog, "MVTX_CarbonFiber$");
0709 m_Detector->FillSupportLVArray(cyssConeLog);
0710
0711 zpos -= (sCYSScylLen / 2 + ServiceProperties::sCYSSFlgSsfCylsf - sCYSSconLen - ServiceProperties::sCYSSFlgSsfConesf);
0712 Ta.set(0., 0., zpos);
0713 Ra.set(0, M_PI * rad, 0.);
0714 av->AddPlacedVolume(cyssConeLog, Ta, &Ra);
0715
0716
0717 const double sCYSSribRint = 97.62 * mm;
0718 const double sCYSSribRext = 99.32 * mm;
0719 const double sCYSSribRmax = 105.30 * mm;
0720 const double sCYSSribWidth = 55.23 * mm;
0721 const double sCYSSribStep1pos = (15.6 + 7.7) / 2 * mm;
0722 const double sCYSSribStep2pos = (47.6 + 39.7) / 2 * mm;
0723 const double sCYSSribThick = 1.7 * mm;
0724
0725 const int nZplanesRib = 10;
0726 const double zPlanesRib[nZplanesRib] = {0. * mm,
0727 sCYSSribStep1pos,
0728 sCYSSribStep1pos,
0729 sCYSSribStep1pos + sCYSSribThick,
0730 sCYSSribStep1pos + sCYSSribThick,
0731 sCYSSribStep2pos,
0732 sCYSSribStep2pos,
0733 sCYSSribStep2pos + sCYSSribThick,
0734 sCYSSribStep2pos + sCYSSribThick,
0735 sCYSSribWidth};
0736
0737 const double rInnerRib[nZplanesRib] = {sCYSSribRint,
0738 sCYSSribRint,
0739 sCYSSribRint,
0740 sCYSSribRint,
0741 sCYSSribRmax - sCYSSribThick,
0742 sCYSSribRmax - sCYSSribThick,
0743 sCYSSribRint,
0744 sCYSSribRint,
0745 sCYSSribRint,
0746 sCYSSribRint};
0747
0748 const double rOuterRib[nZplanesRib] = {sCYSSribRext,
0749 sCYSSribRext,
0750 sCYSSribRmax,
0751 sCYSSribRmax,
0752 sCYSSribRmax,
0753 sCYSSribRmax,
0754 sCYSSribRmax,
0755 sCYSSribRmax,
0756 sCYSSribRext,
0757 sCYSSribRext};
0758
0759 auto *cyssRibSol = new G4Polycone("cyssRibSol", 0., 2. * M_PI * rad,
0760 nZplanesRib, zPlanesRib, rInnerRib, rOuterRib);
0761
0762 auto *cyssRibLog = new G4LogicalVolume(cyssRibSol, matCF, "CYSSrib_LOGIC",
0763 nullptr, nullptr, nullptr);
0764 m_DisplayAction->AddVolume(cyssRibLog, "MVTX_CarbonFiber$");
0765 m_Detector->FillSupportLVArray(cyssRibLog);
0766
0767 zpos -= (sCYSSconLen + ServiceProperties::sCYSSFlgSsfConesf - ServiceProperties::sCYSSFlgSsfRibsf);
0768 Ta.set(0., 0., zpos);
0769 Ra.set(0, 0., 0.);
0770 av->AddPlacedVolume(cyssRibLog, Ta, &Ra);
0771
0772
0773 const double sFlgSRmax = 107.7 * mm;
0774 const double sFlgSRmin = 95.0 * mm;
0775 const double sFlgSRstep = 105.3 * mm;
0776 const double sFlgSChamfeEnd = 9. * mm;
0777 const double sFlgSTotalWidth = 20. * mm;
0778 const double sFlgSRimWidth = 7. * mm;
0779
0780 const int nZplanesFlgS = 4;
0781 const double zPlanesFlgS[nZplanesFlgS] = {0. * mm,
0782 sFlgSRimWidth,
0783 sFlgSRimWidth,
0784 sFlgSTotalWidth};
0785
0786 const double rInnerFlgS[nZplanesFlgS] = {sFlgSRmin,
0787 sFlgSRmin,
0788 sFlgSRmin,
0789 sFlgSRstep - sFlgSChamfeEnd};
0790
0791 const double rOuterFlgS[nZplanesFlgS] = {sFlgSRmax,
0792 sFlgSRmax,
0793 sFlgSRstep,
0794 sFlgSRstep};
0795
0796 auto *cyssFlgSSol = new G4Polycone("cyssFlgSSol", 0., 2. * M_PI * rad,
0797 nZplanesFlgS, zPlanesFlgS, rInnerFlgS, rOuterFlgS);
0798
0799 auto *cyssFlgSLog = new G4LogicalVolume(cyssFlgSSol, matAl, "CYSSFlgS_LOGIC",
0800 nullptr, nullptr, nullptr);
0801 m_DisplayAction->AddVolume(cyssFlgSLog, "MVTX_EW_Al$");
0802 m_Detector->FillSupportLVArray(cyssFlgSLog);
0803
0804 zpos -= (ServiceProperties::sCYSSFlgSsfRibsf);
0805 Ta.set(0., 0., zpos);
0806 Ra.set(0, 0., 0.);
0807 av->AddPlacedVolume(cyssFlgSLog, Ta, &Ra);
0808
0809 return;
0810 }
0811
0812
0813 void PHG4MvtxSupport::CreateServiceBarrel(G4AssemblyVolume *&av)
0814 {
0815
0816
0817
0818
0819
0820
0821
0822
0823
0824
0825
0826
0827
0828
0829
0830
0831
0832 double zpos;
0833
0834 G4ThreeVector Ta;
0835 G4RotationMatrix Ra;
0836
0837
0838 const double sSBFlgNRmax = 107.7 * mm;
0839 const double sSBFlgNRmin = 95.0 * mm;
0840 const double sSBFlgNRimRmax = 105.3 * mm;
0841 const double sSBFlgNRimRmin = 103.3 * mm;
0842 const double sSBFlgNIntThick = 4.92 * mm;
0843 const double sSBFlgNExtThick = 7.00 * mm;
0844 const double sSBFlgNTotThick = 16.0 * mm;
0845
0846 const int nZplanesFlgN = 5;
0847 const double zPlanesFlgN[nZplanesFlgN] = {0. * mm,
0848 sSBFlgNIntThick,
0849 sSBFlgNExtThick,
0850 sSBFlgNExtThick,
0851 sSBFlgNTotThick};
0852
0853 const double rInnerFlgN[nZplanesFlgN] = {sSBFlgNRmin,
0854 sSBFlgNRmin,
0855 sSBFlgNRimRmin,
0856 sSBFlgNRimRmin,
0857 sSBFlgNRimRmin};
0858
0859 const double rOuterFlgN[nZplanesFlgN] = {sSBFlgNRmax,
0860 sSBFlgNRmax,
0861 sSBFlgNRmax,
0862 sSBFlgNRimRmax,
0863 sSBFlgNRimRmax};
0864
0865 auto *sbFlgNSol = new G4Polycone("sbFlgNSol", 0., 2. * M_PI * rad,
0866 nZplanesFlgN, zPlanesFlgN, rInnerFlgN, rOuterFlgN);
0867
0868 auto *matAl = PHG4Detector::GetDetectorMaterial("MVTX_EW_Al$");
0869
0870 auto *sbFlgNLog = new G4LogicalVolume(sbFlgNSol, matAl, "sbFlgN_LOGIC",
0871 nullptr, nullptr, nullptr);
0872 m_DisplayAction->AddVolume(sbFlgNLog, "MVTX_CarbonFiber$");
0873 m_Detector->FillSupportLVArray(sbFlgNLog);
0874
0875 zpos = ServiceProperties::sEndWheelSNHolesZdist / 2 - (ServiceProperties::sEndWStepHoleZpos + ServiceProperties::sEndWStepHoleZdist) + ServiceProperties::sEndWheelNLen - ServiceProperties::sCYSSFlgSsfFlgNsf;
0876 Ta.set(0., 0., zpos);
0877 Ra.set(0, M_PI * rad, 0.);
0878 av->AddPlacedVolume(sbFlgNLog, Ta, &Ra);
0879
0880
0881 const double sSBcylRmin = 105.5 * mm;
0882 const double sSBcylRmax = 107.66 * mm;
0883 const double sSBcylLen = 1197.0 * mm;
0884
0885 auto *sbCylSol = new G4Tubs("SBcyl_SOLID", sSBcylRmin, sSBcylRmax,
0886 sSBcylLen / 2, 0., 2 * M_PI);
0887
0888 auto *matCF = PHG4Detector::GetDetectorMaterial("MVTX_CarbonFiber$");
0889 auto *sbCylLog = new G4LogicalVolume(sbCylSol, matCF, "SBcyl_LOGIC",
0890 nullptr, nullptr, nullptr);
0891 m_DisplayAction->AddVolume(sbCylLog, "MVTX_CarbonFiber$");
0892 m_Detector->FillSupportLVArray(sbCylLog);
0893
0894 zpos -= (sSBcylLen / 2 + sSBFlgNExtThick);
0895 Ta.set(0., 0., zpos);
0896 Ra.set(0, 0., 0.);
0897 av->AddPlacedVolume(sbCylLog, Ta, &Ra);
0898
0899 return;
0900 }
0901
0902
0903 void PHG4MvtxSupport::CreateCable(PHG4MvtxCable *object, G4AssemblyVolume &assemblyVolume)
0904 {
0905 std::string cableMaterials[2] = {object->get_coreMaterial(), "G4_POLYETHYLENE"};
0906
0907 double dX = object->get_xNorth() - object->get_xSouth();
0908 double dY = object->get_yNorth() - object->get_ySouth();
0909 double dZ = object->get_zNorth() - object->get_zSouth();
0910
0911 double rotY = dZ != 0. ? std::atan(dX / dZ) : 0.;
0912 double rotZ = dX != 0. ? std::atan(dY / dX) : 0.;
0913
0914 double setX = (object->get_xSouth() + object->get_xNorth()) / 2;
0915 double setY = (object->get_ySouth() + object->get_yNorth()) / 2;
0916 double setZ = (object->get_zSouth() + object->get_zNorth()) / 2;
0917
0918 double length = std::sqrt(dX * dX + dY * dY + dZ * dZ);
0919 double IR[2] = {0, object->get_coreRadius()};
0920 double OR[2] = {object->get_coreRadius(), object->get_sheathRadius()};
0921
0922 G4RotationMatrix rot;
0923 rot.rotateY(rotY);
0924 rot.rotateZ(rotZ);
0925 G4ThreeVector place;
0926 place.setX(setX);
0927 place.setY(setY);
0928 place.setZ(setZ);
0929 G4Transform3D transform(rot, place);
0930
0931 static G4UserLimits *g4userLimits = new G4UserLimits(0.01);
0932
0933 for (int i = 0; i < 2; ++i)
0934 {
0935 G4Material *trackerMaterial = PHG4Detector::GetDetectorMaterial(cableMaterials[i]);
0936
0937 G4VSolid *cylinderSolid = new G4Tubs(G4String(object->get_name() + "_SOLID"),
0938 IR[i], OR[i], (length / 2.), 0, 2 * M_PI);
0939
0940 G4LogicalVolume *cylinderLogic = new G4LogicalVolume(cylinderSolid, trackerMaterial,
0941 G4String(object->get_name() + "_LOGIC"), nullptr, nullptr, g4userLimits);
0942 m_Detector->FillSupportLVArray(cylinderLogic);
0943
0944 if (i == 0)
0945 {
0946 m_DisplayAction->AddVolume(cylinderLogic, cableMaterials[i]);
0947 }
0948 else
0949 {
0950 m_DisplayAction->AddVolume(cylinderLogic, object->get_color());
0951 }
0952
0953 assemblyVolume.AddPlacedVolume(cylinderLogic, transform);
0954 }
0955 }
0956
0957
0958 void PHG4MvtxSupport::CreateCableBundle(G4AssemblyVolume &assemblyVolume, const std::string &superName,
0959 bool enableSignal, bool enableCooling, bool enablePower,
0960 double x1, double x2, double y1, double y2, double z1, double z2)
0961 {
0962
0963 double samtecCoreRadius = 0.01275 * cm;
0964 double samtecSheathRadius = 0.05 * cm;
0965 double coolingStaveCoreRadius = 0.056 * cm;
0966 double coolingStaveSheathRadius = 0.1 * cm;
0967 double coolingCoreRadius = 0.125 * cm;
0968 double coolingSheathRadius = 0.2 * cm;
0969 double powerLargeCoreRadius = 0.069 * cm;
0970 double powerLargeSheathRadius = 0.158 * cm;
0971 double powerMediumCoreRadius = 0.033 * cm;
0972 double powerMediumSheathRadius = 0.082 * cm;
0973 double powerSmallCoreRadius = 0.028 * cm;
0974 double powerSmallSheathRadius = 0.0573 * cm;
0975
0976 double globalShiftX = 0.;
0977 double globalShiftY = -0.0984 * cm;
0978 double samtecShiftX = -6 * samtecSheathRadius + globalShiftX;
0979 double samtecShiftY = 1 * samtecSheathRadius + globalShiftY;
0980 double coolingShiftX = -3 * coolingSheathRadius + globalShiftX;
0981 double coolingShiftY = -1 * coolingSheathRadius + globalShiftY;
0982 double powerShiftX = 3.5 * powerLargeSheathRadius + globalShiftX;
0983 double powerShiftY = 6.1 * powerLargeSheathRadius + globalShiftY;
0984
0985
0986 if (enableSignal)
0987 {
0988 unsigned int nSamtecWires = 24;
0989 unsigned int nRow = 8;
0990 unsigned int nCol = nSamtecWires / nRow;
0991 for (unsigned int iRow = 0; iRow < nRow; ++iRow)
0992 {
0993 for (unsigned int iCol = 0; iCol < nCol; ++iCol)
0994 {
0995 double deltaX = samtecShiftX + ((iCol + 1) * (samtecSheathRadius * 2.6));
0996 double deltaY = samtecShiftY - ((iRow + 1) * (samtecSheathRadius * 2.1));
0997 PHG4MvtxCable *cable = new PHG4MvtxCable(std::format("{}_samtec_{}_{}", superName, iRow, iCol),
0998 "G4_Cu", samtecCoreRadius, samtecSheathRadius,
0999 x1 + deltaX, x2 + deltaX, y1 + deltaY,
1000 y2 + deltaY, z1, z2, "blue");
1001 CreateCable(cable, assemblyVolume);
1002 delete cable;
1003 }
1004 }
1005 }
1006
1007
1008 if (enableCooling)
1009 {
1010 unsigned int nCool = 2;
1011 std::string cooling_color[2] = {"red", "white"};
1012
1013 auto rx = std::regex{"MVTX_L([0-2])", std::regex_constants::icase};
1014 bool smallCooling = std::regex_search(superName, rx);
1015 PHG4MvtxCable *cable = nullptr;
1016 for (unsigned int iCool = 0; iCool < nCool; ++iCool)
1017 {
1018 double coreRadius = smallCooling ? coolingStaveCoreRadius : coolingCoreRadius;
1019 double sheathRadius = smallCooling ? coolingStaveSheathRadius : coolingSheathRadius;
1020 if (!smallCooling)
1021 {
1022 double deltaX = coolingShiftX + ((iCool + 1) * (sheathRadius * 2));
1023 double deltaY = coolingShiftY + (sheathRadius * 2);
1024 cable = new PHG4MvtxCable(std::format("{}_cooling_{}", superName, iCool),
1025 "G4_WATER", coreRadius, sheathRadius,
1026 x1 + deltaX, x2 + deltaX, y1 + deltaY,
1027 y2 + deltaY, z1, z2, cooling_color[iCool]);
1028 }
1029 else
1030 {
1031 double deltaX = coolingShiftX + (sheathRadius * 2);
1032 double deltaY = coolingShiftY + ((iCool + 1) * (sheathRadius * 2));
1033 cable = new PHG4MvtxCable(std::format("{}_cooling_{}", superName, iCool),
1034 "G4_WATER", coreRadius, sheathRadius,
1035 x1 + deltaX, x2 + deltaX, y1 + deltaY,
1036 y2 + deltaY, z1, z2, cooling_color[iCool]);
1037 }
1038 CreateCable(cable, assemblyVolume);
1039 delete cable;
1040 }
1041 }
1042
1043
1044 if (enablePower)
1045 {
1046 using PowerCableParameters = std::pair<std::pair<std::string, std::string>, std::pair<double, double>>;
1047 std::vector<PowerCableParameters> powerCables;
1048 std::vector<std::vector<double>> powerCableColors;
1049
1050 powerCables.emplace_back(std::make_pair(std::format("{}_digiReturn", superName), "Large"), std::make_pair((-2.5 * powerLargeSheathRadius) + powerShiftX, (-2.5 * powerLargeSheathRadius) + powerShiftY));
1051 powerCables.emplace_back(std::make_pair(std::format("{}_digiSupply", superName), "Large"), std::make_pair((-4.5 * powerLargeSheathRadius) + powerShiftX, (-1.5 * powerLargeSheathRadius) + powerShiftY));
1052 powerCables.emplace_back(std::make_pair(std::format("{}_anaReturn", superName), "Medium"), std::make_pair((-4 * powerLargeSheathRadius) + powerShiftX, (-5.75 * powerMediumSheathRadius) + powerShiftY));
1053 powerCables.emplace_back(std::make_pair(std::format("{}_anaSupply", superName), "Medium"), std::make_pair((-5.1 * powerLargeSheathRadius) + powerShiftX, (-5.75 * powerMediumSheathRadius) + powerShiftY));
1054 powerCables.emplace_back(std::make_pair(std::format("{}_digiSense", superName), "Small"), std::make_pair((-10 * powerSmallSheathRadius) + powerShiftX, (-1 * powerSmallSheathRadius) + powerShiftY));
1055 powerCables.emplace_back(std::make_pair(std::format("{}_anaSense", superName), "Small"), std::make_pair((-8 * powerSmallSheathRadius) + powerShiftX, (-2 * powerSmallSheathRadius) + powerShiftY));
1056 powerCables.emplace_back(std::make_pair(std::format("{}_bias", superName), "Small"), std::make_pair((-6 * powerSmallSheathRadius) + powerShiftX, (-3 * powerSmallSheathRadius) + powerShiftY));
1057 powerCables.emplace_back(std::make_pair(std::format("{}_ground", superName), "Small"), std::make_pair((-4 * powerSmallSheathRadius) + powerShiftX, (-4 * powerSmallSheathRadius) + powerShiftY));
1058
1059 for (PowerCableParameters &powerCable : powerCables)
1060 {
1061 double coreRad;
1062 double sheathRad;
1063 std::string cableColor;
1064 std::string cableType = powerCable.first.second;
1065 std::string cableName = powerCable.first.first;
1066 if (cableType == "Small")
1067 {
1068 coreRad = powerSmallCoreRadius;
1069 sheathRad = powerSmallSheathRadius;
1070 }
1071 else if (cableType == "Medium")
1072 {
1073 coreRad = powerMediumCoreRadius;
1074 sheathRad = powerMediumSheathRadius;
1075 }
1076 else
1077 {
1078 coreRad = powerLargeCoreRadius;
1079 sheathRad = powerLargeSheathRadius;
1080 }
1081
1082 if (cableName == std::format("{}_digiReturn", superName))
1083 {
1084 cableColor = "black";
1085 }
1086 if (cableName == std::format("{}_digiSupply", superName))
1087 {
1088 cableColor = "red";
1089 }
1090 if (cableName == std::format("{}_anaReturn", superName))
1091 {
1092 cableColor = "black";
1093 }
1094 if (cableName == std::format("{}_anaSupply", superName))
1095 {
1096 cableColor = "red";
1097 }
1098 if (cableName == std::format("{}_digiSense", superName))
1099 {
1100 cableColor = "white";
1101 }
1102 if (cableName == std::format("{}_anaSense", superName))
1103 {
1104 cableColor = "green";
1105 }
1106 if (cableName == std::format("{}_bias", superName))
1107 {
1108 cableColor = "white";
1109 }
1110 if (cableName == std::format("{}_ground", superName))
1111 {
1112 cableColor = "green";
1113 }
1114
1115 PHG4MvtxCable *cable = new PHG4MvtxCable(powerCable.first.first, "G4_Cu", coreRad, sheathRad,
1116 (x1 + powerCable.second.first), (x2 + powerCable.second.first),
1117 (y1 + powerCable.second.second), (y2 + powerCable.second.second), z1, z2, cableColor);
1118 CreateCable(cable, assemblyVolume);
1119 delete cable;
1120 }
1121 }
1122 }
1123
1124
1125 G4AssemblyVolume *PHG4MvtxSupport::buildBarrelCable()
1126 {
1127 G4AssemblyVolume *av = new G4AssemblyVolume();
1128
1129 CreateCableBundle(*av, "barrelCable", true, true, false, 0, 0, 0, 0,
1130 ServiceProperties::BarrelCableEnd, ServiceProperties::BarrelCableStart);
1131 CreateCableBundle(*av, "barrelCable", false, false, true, 0, 0, 0, 0,
1132 ServiceProperties::BarrelCableEnd,
1133 -ServiceProperties::sEndWheelSNHolesZdist / 2 + (ServiceProperties::sEndWStepHoleZpos + ServiceProperties::sEndWStepHoleZdist) - 40 * cm);
1134 return av;
1135 }
1136
1137
1138 G4AssemblyVolume *PHG4MvtxSupport::buildLayerCables(const int &lay)
1139 {
1140 G4AssemblyVolume *av = new G4AssemblyVolume();
1141
1142 double rOuter[3] = {(103 - 2.) / 2 * mm, (149 - 2.24) / 2 * mm, (195 - 2.24) / 2 * mm};
1143 double zConeLen[3] = {186.8 * mm, 179.74 * mm, 223 * mm};
1144 double zMax = -ServiceProperties::sEndWheelSNHolesZdist / 2 + (ServiceProperties::sEndWStepHoleZpos + ServiceProperties::sEndWStepHoleZdist) - 17 * mm - zConeLen[lay];
1145
1146 CreateCableBundle(*av, std::string("MVTX_L" + std::to_string(lay) + "Cable"), true, true, false,
1147 rOuter[lay] - 3 * mm, rOuter[lay] - 5 * mm, 0, 0,
1148 ServiceProperties::BarrelCableStart + 1 * mm, zMax);
1149
1150
1151
1152
1153
1154
1155
1156
1157 return av;
1158 }
1159
1160
1161 void PHG4MvtxSupport::ConstructMvtxSupport(G4LogicalVolume *&lv)
1162 {
1163 CreateMvtxSupportMaterials();
1164 m_avSupport = new G4AssemblyVolume();
1165
1166 CreateEndWheelsSideN(m_avSupport);
1167 CreateEndWheelsSideS(m_avSupport);
1168 CreateConeLayers(m_avSupport);
1169 CreateCYSS(m_avSupport);
1170 CreateServiceBarrel(m_avSupport);
1171
1172 G4RotationMatrix Ra;
1173 G4ThreeVector Ta = G4ThreeVector();
1174 G4Transform3D Tr(Ra, Ta);
1175 m_avSupport->MakeImprint(lv, Tr, 0, m_overlapCheck);
1176
1177 unsigned int nStaves[PHG4MvtxDefs::kNLayers];
1178 unsigned int totStaves = 0;
1179 for (unsigned int i = 0; i < PHG4MvtxDefs::kNLayers; ++i)
1180 {
1181 nStaves[i] = (int) PHG4MvtxDefs::mvtxdat[i][PHG4MvtxDefs::kNStave];
1182 totStaves += nStaves[i];
1183 }
1184
1185 m_avBarrelCable = buildBarrelCable();
1186 G4ThreeVector placeBarrelCable;
1187 for (unsigned int i = 0; i < totStaves; ++i)
1188 {
1189 double phi = (2.0 * M_PI / totStaves) * i;
1190 placeBarrelCable.setX((ServiceProperties::BarrelRadius - 1 * cm) * std::cos(phi));
1191 placeBarrelCable.setY((ServiceProperties::BarrelRadius - 1 * cm) * std::sin(phi));
1192 G4RotationMatrix rotBarrelCable;
1193 rotBarrelCable.rotateZ(phi + (-90. * deg));
1194 G4Transform3D transformBarrelCable(rotBarrelCable, placeBarrelCable);
1195 m_avBarrelCable->MakeImprint(lv, transformBarrelCable, 0, m_overlapCheck);
1196 }
1197
1198 for (unsigned int iLayer = 0; iLayer < PHG4MvtxDefs::kNLayers; ++iLayer)
1199 {
1200 m_avLayerCable[iLayer] = buildLayerCables(iLayer);
1201 for (unsigned int iStave = 0; iStave < nStaves[iLayer]; ++iStave)
1202 {
1203 G4RotationMatrix rotCable;
1204 G4ThreeVector placeCable;
1205 double phi = (2.0 * M_PI / nStaves[iLayer]) * iStave;
1206 placeCable.setX(std::cos(phi));
1207 placeCable.setY(std::sin(phi));
1208 rotCable.rotateZ(phi + ((90. + ServiceProperties::cableRotate[iLayer]) * deg));
1209 G4Transform3D transformCable(rotCable, placeCable);
1210 m_avLayerCable[iLayer]->MakeImprint(lv, transformCable, 0, m_overlapCheck);
1211 }
1212 }
1213 }