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