Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PHG4MvtxSupport.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file PHG4MvtxSupport.cc
1 #include "PHG4MvtxSupport.h"
2 
3 #include "PHG4MvtxCable.h"
4 #include "PHG4MvtxDetector.h"
6 
7 #include <g4main/PHG4Detector.h>
8 
9 #include <Geant4/G4AssemblyVolume.hh>
10 #include <Geant4/G4Box.hh>
11 #include <Geant4/G4LogicalVolume.hh>
12 #include <Geant4/G4Material.hh>
13 #include <Geant4/G4Polycone.hh>
14 #include <Geant4/G4RotationMatrix.hh> // for G4RotationMatrix
15 #include <Geant4/G4String.hh>
16 #include <Geant4/G4SubtractionSolid.hh>
17 #include <Geant4/G4SystemOfUnits.hh>
18 #include <Geant4/G4ThreeVector.hh> // for G4ThreeVector
19 #include <Geant4/G4Transform3D.hh>
20 #include <Geant4/G4Tubs.hh>
21 #include <Geant4/G4Types.hh>
22 #include <Geant4/G4UserLimits.hh>
23 
24 #pragma GCC diagnostic push
25 #pragma GCC diagnostic ignored "-Wshadow"
26 #include <boost/format.hpp>
27 #pragma GCC diagnostic pop
28 
29 #include <algorithm> // for max
30 #include <cmath> // for M_PI, atan, cos, sin
31 #include <iostream> // for operator<<, basic_...
32 #include <regex> // for regex
33 #include <utility> // for pair, make_pair
34 #include <vector>
35 
36 class G4VSolid;
37 
38 namespace ServiceProperties
39 {
40  // std::string materials[] = {"G4_Cu", "MVTX_CarbonFiber$", "G4_POLYETHYLENE"};
41  // const int nMaterials = sizeof(materials) / sizeof(materials[0]);
42 
43  const double sEndWheelSNHolesZdist = 308.0 * mm; // ALIITSUP0187,0177,0143
44  const double sEndWStepHoleZpos = 4. * mm;
45  const double sEndWStepHoleZdist = 4. * mm;
46  const double sEndWheelNLen = 30. * mm;
47 
48  const double sCYSSFlgSsfFlgNsf = 606.59 * mm; // sf -> south face
49  const double sCYSSFlgSsfCylsf = 181. * mm;
50  const double sCYSSFlgSsfConesf = 7. * mm;
51  const double sCYSSFlgSsfRibsf = 50. * mm;
52  const double sPP2sfSBsf = 791.77 * mm;
53  const double sPP2Len = 80 * mm;
54 
55  double ServiceEnd = -7.21 * cm;
56  double ServiceOffset = -16.0 * cm;
57  double BarrelOffset = 18.679 * cm;
58  double BarrelRadius = 10.33 * cm; // Inner radious of service barrel
59  double BarrelThickness = 0.436 * cm; // Thickness in cm
60  double BarrelLength = 1214.4 * mm; // Length of cylinder in cm
63  double LayerThickness = 0.1 * cm; //
64  double CYSSConeThickness = 0.216 * cm;
65  double CYSSRibThickness = 0.170 * cm;
66  double cableRotate[3] = {10., 5., 5.}; // Rotate the cables to line up with the staves in deg
67 } // namespace ServiceProperties
68 
69 using namespace ServiceProperties;
70 
71 //________________________________________________________________________________
73  : m_Detector(detector)
74  , m_DisplayAction(dispAct)
75  , m_overlapCheck(overlapCheck)
76 {
77 }
78 
79 //________________________________________________________________________________
81 {
82  if (m_avSupport)
83  {
84  delete m_avSupport;
85  }
86  if (m_avBarrelCable)
87  {
88  delete m_avBarrelCable;
89  }
90  for (auto av : m_avLayerCable)
91  {
92  if (av)
93  {
94  delete av;
95  }
96  }
97 }
98 
99 //________________________________________________________________________________
101 {
102  G4double density;
103  G4int natoms;
104  G4String symbol;
105  G4String material = "MVTX_EW_Al$";
106  if (!PHG4Detector::GetDetectorMaterial(material.c_str(), false))
107  {
108  auto MVTX_Al = new G4Material(material.c_str(), density = 2.7 * g / cm3,
109  natoms = 1, kStateSolid);
110  MVTX_Al->AddMaterial(PHG4Detector::GetDetectorMaterial("G4_Al"), 100 * perCent);
111  }
112 
113  material = "MVTX_Epoxy$";
114  if (!PHG4Detector::GetDetectorMaterial(material.c_str(), false))
115  {
116  auto MVTX_Epoxy = new G4Material(material.c_str(), density = 1.56 * g / cm3, natoms = 4);
117  MVTX_Epoxy->AddElement(PHG4Detector::GetDetectorElement("H", true), 32); // Hydrogen
118  MVTX_Epoxy->AddElement(PHG4Detector::GetDetectorElement("C", true), 2); // Nitrogen
119  MVTX_Epoxy->AddElement(PHG4Detector::GetDetectorElement("N", true), 4); // Oxygen
120  MVTX_Epoxy->AddElement(PHG4Detector::GetDetectorElement("O", true), 15); // Carbon
121  }
122 
123  material = "MVTX_CarbonFiber$";
124  if (!PHG4Detector::GetDetectorMaterial(material.c_str(), false))
125  {
126  auto MVTX_CF = new G4Material(material.c_str(), density = 1.987 * g / cm3,
127  natoms = 2);
128  MVTX_CF->AddMaterial(PHG4Detector::GetDetectorMaterial("G4_C"), 70 * perCent); // Carbon (NX-80-240)
129  MVTX_CF->AddMaterial(PHG4Detector::GetDetectorMaterial("MVTX_Epoxy$"), 30 * perCent); // Epoxy (EX-1515)
130  }
131 }
132 
133 //________________________________________________________________________________
134 void PHG4MvtxSupport::CreateEndWheelsSideN(G4AssemblyVolume *&av)
135 {
136  for (unsigned int iLay = 0; iLay < PHG4MvtxDefs::kNLayers; iLay++)
137  {
138  GetEndWheelSideN(iLay, av);
139  }
140 }
141 
142 //________________________________________________________________________________
143 void PHG4MvtxSupport::GetEndWheelSideN(const int lay, G4AssemblyVolume *&endWheel)
144 {
145  //
146  // Creates the single End Wheel on Side North
147  // for a given layer of the MVTX detector
148  // (Layer 0: MVTX-2-S-00001)
149  // (Layer 1: MVTX-2-S-00016)
150  // (Layer 2: MVTX-2-S-00023)
151  //
152  // Input:
153  // iLay : the layer number
154  // endWheel : the whole end wheel volume
155  // where to place the current created wheel
156  // Output:
157  //
158  // Return:
159  //
160  // Created: 10 Jan 2023 Yasser Corrales Morales
161  // (partially based on M. Sitta implementation in ITS2)
162  //
163 
164  // The Basis Cone North Side is two halves,
165  // but for sake of simplicity, so here they are made as a single cone.
166  const double sEndWheelNRmax[3] = {30.57 * mm, 38.59 * mm, 46.30 * mm};
167  const double sEndWheelNRmin[3] = {22.83 * mm, 30.67 * mm, 38.70 * mm};
168  const double sEndWheelNWallR[3] = {29.57 * mm, 37.59 * mm, 45.30 * mm};
169  const double sEndWheelNThick = 2.8 * mm;
170 
171  const int sEndWNBaseNBigHoles = 6;
172  const int sEndWNBaseNSmallHoles = 5;
173  const double sEndWNBaseBigHoleD = 4 * mm;
174  const double sEndWNBaseSmallHoleD = 1.6 * mm;
175  const double sEndWNBaseHolesR[3] = {27. * mm, 35. * mm, 42.7 * mm};
176  const double sEndWNBaseHolesPhi = 15.; // Deg
177 
178  const int sEndWNWallNHoles[3] = {6, 8, 10};
179  const double sEndWNWallHoleD = 4.5 * mm;
180 
181  // The End Wheel Steps
182  const double sEndWNStepXlen[3] = {9.88 * mm, 11.2 * mm, 8.38 * mm};
183  const double sEndWNStepYdispl[3] = {26.521 * mm, 33.891 * mm, 41.64 * mm};
184  const double sEndWNStepHolePhi[3] = {30.0, 22.5, 18.0}; // Deg
185  const double sEndWNStepHoleTilt[3] = {0., 0.295, 0.297}; // Rad
186 
187  const double sEndWNStepZlen = sEndWheelNLen - sEndWheelNThick;
188 
189  // local varianbles
190  double rmin, rmax, phimin, dphi;
191  double xpos, ypos, zpos, rpos;
192  double xlen, ylen;
193 
194  auto Ta = G4ThreeVector();
195  auto Ra = G4RotationMatrix();
196 
197  const unsigned short nZplanes = 4;
198  const double zPlane[nZplanes] = {0. * mm,
199  sEndWheelNLen - sEndWheelNThick,
200  sEndWheelNLen - sEndWheelNThick,
201  sEndWheelNLen};
202 
203  const double rInner[nZplanes] = {sEndWheelNWallR[lay], sEndWheelNWallR[lay],
204  sEndWheelNRmin[lay], sEndWheelNRmin[lay]};
205 
206  const double rOuter[nZplanes] = {sEndWheelNRmax[lay], sEndWheelNRmax[lay],
207  sEndWheelNRmax[lay], sEndWheelNRmax[lay]};
208 
209  G4VSolid *endWNBasis = new G4Polycone(std::string("endwnbasis" + std::to_string(lay)), 0., 2. * M_PI * rad,
210  nZplanes, zPlane, rInner, rOuter);
211 
212  // The holes in the veritcal wall
213  auto endwnwalhol = new G4Tubs(std::string("endwnwalhol" + std::to_string(lay)), 0, sEndWNWallHoleD / 2,
214  1.5 * (sEndWheelNRmax[lay] - sEndWheelNWallR[lay]),
215  0, 2 * M_PI * rad);
216 
217  rmin = (sEndWheelNRmax[lay] + sEndWheelNWallR[lay]) / 2;
218  zpos = sEndWStepHoleZpos;
219  dphi = 180. / sEndWNWallNHoles[lay];
220  phimin = dphi / 2;
221  for (int ihole = 0; ihole < 2 * sEndWNWallNHoles[lay]; ihole++)
222  {
223  double phi = phimin + ihole * dphi;
224  xpos = rmin * sin(phi * deg);
225  ypos = rmin * cos(phi * deg);
226  Ra.set(-phi * deg, 90 * deg, 0.);
227  Ta.set(xpos, ypos, zpos);
228  endWNBasis = new G4SubtractionSolid(std::string("endwnbasis-endwnwalhol" + std::to_string(ihole) + "l" + std::to_string(lay)),
229  endWNBasis, endwnwalhol, &Ra, Ta);
230  }
231 
232  // The holes in the base
233  auto endwnbasBhol = new G4Tubs(std::string("endwnbasBhol" + std::to_string(lay)), 0, sEndWNBaseBigHoleD / 2,
234  1.5 * sEndWheelNThick, 0, 2 * M_PI * rad);
235 
236  auto endwnbasShol = new G4Tubs(std::string("endwnbasShol" + std::to_string(lay)), 0, sEndWNBaseSmallHoleD / 2,
237  1.5 * sEndWheelNThick, 0, 2 * M_PI * rad);
238 
239  rmin = sEndWNBaseHolesR[lay];
240  zpos = sEndWheelNLen - (sEndWheelNThick / 2);
241  phimin = 0.;
242  for (int ihole = 0; ihole < (sEndWNBaseNBigHoles + sEndWNBaseNSmallHoles); ihole++)
243  {
244  phimin += sEndWNBaseHolesPhi;
245  xpos = rmin * cos(phimin * deg);
246  ypos = rmin * sin(phimin * deg);
247  Ra.set(0., 0., 0.);
248  Ta.set(xpos, ypos, zpos);
249  auto endwnbashol = (ihole < 2 || ihole == 5 || ihole > 8) ? endwnbasShol : endwnbasBhol;
250  endWNBasis = new G4SubtractionSolid(std::string("endwnbasis-endwnwalhol" + std::to_string(ihole) + "l" + std::to_string(lay) + "a"),
251  endWNBasis, endwnbashol, &Ra, Ta);
252  Ta = G4ThreeVector(-xpos, -ypos, zpos);
253  endWNBasis = new G4SubtractionSolid(std::string("endwnbasis-endwnwalhol" + std::to_string(ihole) + "l" + std::to_string(lay) + "b"),
254  endWNBasis, endwnbashol, &Ra, Ta);
255  }
256 
257  // Now the Step as a Composite Shape (subtraction of a Pcon from a BBox)
258  // (cutting volume should be slightly larger than desired region)
259  rmin = sEndWheelNWallR[lay];
260  xlen = sEndWNStepXlen[lay] - ((lay == 1) ? 0.01 * mm : 0. * mm);
261  double xDispl = sqrt(rmin * rmin - sEndWNStepYdispl[lay] * sEndWNStepYdispl[lay]) - xlen;
262  ylen = sqrt(rmin * rmin - xDispl * xDispl) - sEndWNStepYdispl[lay];
263 
264  auto stepBoxNSh = new G4Box(std::string("stepBoxNSh" + std::to_string(lay)), xlen / 2, ylen / 2,
265  (sEndWNStepZlen / 2) - 0.05 * mm);
266 
267  xpos = xDispl + stepBoxNSh->GetXHalfLength();
268  ypos = sEndWNStepYdispl[lay] + stepBoxNSh->GetYHalfLength();
269  rpos = std::sqrt(xpos * xpos + ypos * ypos);
270 
271  phimin = (90. * deg) - acos(sEndWNStepYdispl[lay] / rmin) * rad - 5 * deg;
272  dphi = (90. * deg) - asin(xDispl / rmin) * rad - phimin + 5 * deg;
273  rmax = rmin + 2 * stepBoxNSh->GetYHalfLength();
274 
275  auto stepTubNSh = new G4Tubs(std::string("stepTubNSh" + std::to_string(lay)), rmin, rmax,
276  1.5 * sEndWNStepZlen / 2, phimin, dphi);
277  Ra.set(0., 0., 0.);
278  Ta.set(-xpos, -ypos, 0);
279  auto stepNSh = new G4SubtractionSolid(std::string("stepNSh" + std::to_string(lay)),
280  stepBoxNSh, stepTubNSh, &Ra, Ta);
281 
282  auto matAl = PHG4Detector::GetDetectorMaterial("MVTX_EW_Al$");
283 
284  auto endWheelNvol = new G4LogicalVolume(endWNBasis, matAl, std::string("EndWheelNBasis" + std::to_string(lay)));
285  m_DisplayAction->AddVolume(endWheelNvol, "red");
286  m_Detector->FillSupportLVArray(endWheelNvol);
287 
288  auto stepNShLogVol = new G4LogicalVolume(stepNSh, matAl, std::string("StepNL" + std::to_string(lay) + "_LOGIC"));
289  m_DisplayAction->AddVolume(stepNShLogVol, "red");
290  m_Detector->FillSupportLVArray(stepNShLogVol);
291 
292  // Finally put everything in the mother volume
294  Ra.set(0., 0., 0.);
295  Ta.set(0, 0, zpos);
296  endWheel->AddPlacedVolume(endWheelNvol, Ta, &Ra);
297 
298  dphi = std::atan(ypos / xpos);
299  double phi0 = PHG4MvtxDefs::mvtxdat[lay][PHG4MvtxDefs::kPhi0];
300  const int numberOfStaves = PHG4MvtxDefs::mvtxdat[lay][PHG4MvtxDefs::kNStave];
301  zpos += (stepBoxNSh->GetZHalfLength());
302  for (int j = 0; j < numberOfStaves; j++)
303  {
304  double phi = phi0 * rad;
305  phi += j * sEndWNStepHolePhi[lay] * deg;
306  phi -= sEndWNStepHoleTilt[lay];
307  xpos = rpos * cos(phi);
308  ypos = rpos * sin(phi);
309  Ra.set(0., 0., dphi - phi);
310  Ta.set(xpos, ypos, zpos);
311  endWheel->AddPlacedVolume(stepNShLogVol, Ta, &Ra);
312  }
313 
314  return;
315 }
316 
317 //________________________________________________________________________________
318 void PHG4MvtxSupport::CreateEndWheelsSideS(G4AssemblyVolume *&av)
319 {
320  for (unsigned int iLay = 0; iLay < PHG4MvtxDefs::kNLayers; iLay++)
321  {
322  GetEndWheelSideS(iLay, av);
323  }
324 }
325 
326 //________________________________________________________________________________
327 void PHG4MvtxSupport::GetEndWheelSideS(const int lay, G4AssemblyVolume *&endWheel)
328 {
329  //
330  // Creates the single End Wheel on Side South
331  // for a given layer of the MVTX detector
332  // (Layer 0: MVTX-2-S-00002)
333  // (Layer 1: MVTX-2-S-00017)
334  // (Layer 2: MVTX-2-S-00024)
335  //
336  // Input:
337  // iLay : the layer number
338  // endWheel : the whole end wheel volume
339  // where to place the current created wheel
340  // Output:
341  //
342  // Return:
343  //
344  // Created: 17 Jan 2023 Yasser Corrales Morales
345  // (partially based on M. Sitta implementation in ITS2)
346  //
347 
348  // The Basis Cone South Side is two halves,
349  // but for sake of simplicity, so here they are made as a single cone.
350  const double sEWSExtSectRmax[3] = {30.97 * mm, 38.99 * mm, 46.74 * mm};
351  const double sEWSExtSectThick[3] = {0.97 * mm, 1.20 * mm, 1.01 * mm};
352 
353  const double sEWSIntSectRmax[3] = {29.77 * mm, 37.79 * mm, 45.54 * mm};
354  const double sEWSIntSectRmin[3] = {28.80 * mm, 36.80 * mm, 44.50 * mm};
355  const double sEWSIntSectLongLen = 26 * mm;
356  const double sEWSIntSectShortLen = 25 * mm;
357 
358  const double sEWSTotalLen = 42. * mm;
359 
360  const int sEndWSWallNHoles[3] = {6, 8, 10};
361  const double sEndWSWallHoleD = 4.5 * mm;
362 
363  const double sEndWSStepXlen[3] = {10.80 * mm, 10.05 * mm, 9.45 * mm};
364  const double sEndWSStepYdispl[3] = {26.52 * mm, 33.89 * mm, 41.64 * mm};
365  const double sEndWSStepHolePhi[3] = {30.0, 22.5, 18.0}; // Deg
366  const double sEndWSStepHoleTilt[3] = {0., 0.295, 0.297}; // Rad
367 
368  const double sEndWSStepZlen = sEWSTotalLen - sEWSIntSectLongLen;
369  const double sEndWheelNWallR = sEWSExtSectRmax[lay] - sEWSExtSectThick[lay] + 0.05 * mm;
370 
371  // local varianbles
372  double rmin, rmax, phimin, dphi;
373  double xpos, ypos, zpos, rpos;
374  double xlen, ylen;
375 
376  auto Ta = G4ThreeVector();
377  auto Ra = G4RotationMatrix();
378 
379  const unsigned short nZplanes = 6;
380  const double zPlane[nZplanes] = {0. * mm,
381  sEWSTotalLen - sEWSIntSectLongLen,
382  sEWSTotalLen - sEWSIntSectLongLen,
383  sEWSTotalLen - sEWSIntSectShortLen,
384  sEWSTotalLen - sEWSIntSectShortLen,
385  sEWSTotalLen};
386 
387  const double rInner[nZplanes] = {sEndWheelNWallR,
388  sEndWheelNWallR,
389  sEWSIntSectRmin[lay],
390  sEWSIntSectRmin[lay],
391  sEWSIntSectRmin[lay],
392  sEWSIntSectRmin[lay]};
393 
394  const double rOuter[nZplanes] = {sEWSExtSectRmax[lay],
395  sEWSExtSectRmax[lay],
396  sEWSExtSectRmax[lay],
397  sEWSExtSectRmax[lay],
398  sEWSIntSectRmax[lay],
399  sEWSIntSectRmax[lay]};
400 
401  G4VSolid *endWSBasis = new G4Polycone(std::string("endwsbasis" + std::to_string(lay)), 0., 2. * M_PI * rad,
402  nZplanes, zPlane, rInner, rOuter);
403 
404  // The holes in the veritcal wall
405  auto endwswalhol = new G4Tubs(std::string("endwswalhol" + std::to_string(lay)), 0, sEndWSWallHoleD / 2,
406  1.5 * sEWSExtSectThick[lay],
407  0, 2 * M_PI * rad);
408 
409  rmin = sEWSExtSectRmax[lay] - sEWSExtSectThick[lay] / 2;
410  zpos = sEndWStepHoleZpos;
411  dphi = 180. / sEndWSWallNHoles[lay];
412  phimin = dphi / 2;
413  for (int ihole = 0; ihole < 2 * sEndWSWallNHoles[lay]; ihole++)
414  {
415  double phi = phimin + ihole * dphi;
416  xpos = rmin * sin(phi * deg);
417  ypos = rmin * cos(phi * deg);
418  Ra.set(-phi * deg, 90 * deg, 0);
419  Ta.set(xpos, ypos, zpos);
420  endWSBasis = new G4SubtractionSolid(std::string("endwsbasis-endwswalhol" + std::to_string(ihole) + "l" + std::to_string(lay)),
421  endWSBasis, endwswalhol, &Ra, Ta);
422  }
423 
424  // Now the Step as a Composite Shape (subtraction of a Pcon from a BBox)
425  // (cutting volume should be slightly larger than desired region)
426  rmin = sEWSExtSectRmax[lay] - sEWSExtSectThick[lay];
427  xlen = sEndWSStepXlen[lay];
428  double xDispl = sqrt(rmin * rmin - sEndWSStepYdispl[lay] * sEndWSStepYdispl[lay]) - xlen;
429  ylen = sqrt(rmin * rmin - xDispl * xDispl) - sEndWSStepYdispl[lay];
430 
431  auto stepBoxSSh = new G4Box(std::string("stepBoxSSh" + std::to_string(lay)), xlen / 2, ylen / 2,
432  (sEndWSStepZlen / 2) - 0.05 * mm);
433 
434  xpos = xDispl + stepBoxSSh->GetXHalfLength();
435  ypos = sEndWSStepYdispl[lay] + stepBoxSSh->GetYHalfLength();
436  rpos = std::sqrt(xpos * xpos + ypos * ypos);
437 
438  phimin = (90. * deg) - acos(sEndWSStepYdispl[lay] / rmin) * rad - 5 * deg;
439  dphi = (90. * deg) - asin(xDispl / rmin) * rad - phimin + 5 * deg;
440  rmax = rmin + 2 * stepBoxSSh->GetYHalfLength();
441 
442  auto stepTubSSh = new G4Tubs(std::string("stepTubSSh" + std::to_string(lay)), rmin, rmax,
443  1.5 * sEndWSStepZlen / 2, phimin, dphi);
444  Ra.set(0., 0., 0.);
445  Ta.set(-xpos, -ypos, 0.);
446  auto stepSSh = new G4SubtractionSolid(std::string("stepSSh" + std::to_string(lay)),
447  stepBoxSSh, stepTubSSh, &Ra, Ta);
448 
449  auto matAl = PHG4Detector::GetDetectorMaterial("MVTX_EW_Al$");
450 
451  auto endWheelSvol = new G4LogicalVolume(endWSBasis, matAl, std::string("EndWheelSBasis" + std::to_string(lay)));
452  m_DisplayAction->AddVolume(endWheelSvol, "red");
453  m_Detector->FillSupportLVArray(endWheelSvol);
454 
455  auto stepSShLogVol = new G4LogicalVolume(stepSSh, matAl, std::string("StepSL" + std::to_string(lay) + "_LOGIC"));
456  m_DisplayAction->AddVolume(stepSShLogVol, "red");
457  m_Detector->FillSupportLVArray(stepSShLogVol);
458 
459  // Finally put everything in the mother volume
461  Ra.set(0., M_PI * rad, 0.);
462  Ta.set(0, 0, -zpos);
463  endWheel->AddPlacedVolume(endWheelSvol, Ta, &Ra);
464 
465  dphi = std::atan(ypos / xpos);
466  double phi0 = PHG4MvtxDefs::mvtxdat[lay][PHG4MvtxDefs::kPhi0];
467  const int numberOfStaves = PHG4MvtxDefs::mvtxdat[lay][PHG4MvtxDefs::kNStave];
468  zpos += (stepBoxSSh->GetZHalfLength());
469  for (int j = 0; j < numberOfStaves; j++)
470  {
471  double phi = phi0 * rad;
472  phi += j * sEndWSStepHolePhi[lay] * deg;
473  phi -= sEndWSStepHoleTilt[lay];
474  xpos = rpos * cos(phi);
475  ypos = rpos * sin(phi);
476  Ra.set(0., 0., dphi - phi);
477  Ta.set(xpos, ypos, -zpos);
478  endWheel->AddPlacedVolume(stepSShLogVol, Ta, &Ra);
479  }
480 
481  return;
482 }
483 
484 //________________________________________________________________________________
485 void PHG4MvtxSupport::CreateConeLayers(G4AssemblyVolume *&av)
486 {
487  for (unsigned int iLay = 0; iLay < PHG4MvtxDefs::kNLayers; iLay++)
488  {
489  GetConeVolume(iLay, av);
490  }
491 }
492 
493 //________________________________________________________________________________
494 void PHG4MvtxSupport::GetConeVolume(int lay, G4AssemblyVolume *&av)
495 {
496  //
497  // Creates the single CF cone
498  // for a given layer of the MVTX detector
499  // (Layer 0: MVTX-2-S-00005)
500  // (Layer 1: MVTX-2-S-00032)
501  // (Layer 2: MVTX-2-S-00047)
502  //
503  // Input:
504  // iLay : the layer number
505  //
506  // Output:
507  //
508  // Return:
509  //
510  // Created: 20 Jan 2023 Yasser Corrales Morales
511  //
512 
513  const double sEndWheelSExtSectLen = 17 * mm;
514 
515  const double sThickness[3] = {1. * mm, 1.12 * mm, 1.12 * mm};
516  const double sBigCylDmax[3] = {103 * mm, 149 * mm, 195 * mm};
517  const double sBigCylDmin = sBigCylDmax[lay] - 2 * sThickness[lay];
518  const double sSmallCylDmin[3] = {59.94 * mm, 75.98 * mm, 91.48 * mm};
519  const double sTotalLen[3] = {186.8 * mm, 179.74 * mm, 223 * mm};
520  const double sSmallCylLen[3] = {91.86 * mm, 89.38 * mm, 85.38 * mm};
521  const double sConePlusSCLen[3] = {165.79 * mm, 158.51 * mm, 152.06 * mm};
522 
523  const int nZplanes = 4;
524  const double zPlane[nZplanes] = {0 * mm,
525  -sSmallCylLen[lay],
526  -sConePlusSCLen[lay],
527  -sTotalLen[lay]};
528 
529  const double rInner[nZplanes] = {sSmallCylDmin[lay] / 2,
530  sSmallCylDmin[lay] / 2,
531  sBigCylDmin / 2,
532  sBigCylDmin / 2};
533 
534  const double rOuter[nZplanes] = {sSmallCylDmin[lay] / 2 + sThickness[lay],
535  sSmallCylDmin[lay] / 2 + sThickness[lay],
536  sBigCylDmax[lay] / 2,
537  sBigCylDmax[lay] / 2};
538 
539  auto coneSolid = new G4Polycone(std::string("cfConeL" + std::to_string(lay)), 0., 2. * M_PI * rad,
540  nZplanes, zPlane, rInner, rOuter);
541 
542  auto matCF = PHG4Detector::GetDetectorMaterial("MVTX_CarbonFiber$");
543 
544  auto coneLogVol = new G4LogicalVolume(coneSolid, matCF,
545  std::string("ConeL" + std::to_string(lay) + "_LOGIC"),
546  nullptr, nullptr, nullptr);
547 
548  m_DisplayAction->AddVolume(coneLogVol, "MVTX_CarbonFiber$");
549  m_Detector->FillSupportLVArray(coneLogVol);
550 
551  double zpos = sEndWheelSNHolesZdist / 2 - (sEndWStepHoleZpos + sEndWStepHoleZdist) + sEndWheelSExtSectLen;
552  G4ThreeVector Ta = G4ThreeVector(0., 0., -zpos);
553  G4RotationMatrix Ra;
554  av->AddPlacedVolume(coneLogVol, Ta, &Ra);
555 
556  return;
557 }
558 
559 //________________________________________________________________________________
560 void PHG4MvtxSupport::CreateCYSS(G4AssemblyVolume *&av)
561 {
562  //
563  // Creates the CYSS
564  // (MVTX-s-S-00080)
565  // (MVTX-2-S-00075)
566  // (MVTX-s-S-00079)
567  // (MVTX-s-S-00077)
568  // (MVTX-s-S-00078)
569  // (MVTX-s-S-00076)
570  //
571  // Input:
572  // av : assembly volume
573  //
574  // Output:
575  //
576  // Return:
577  //
578  //
579  // Created: 20 Jan 2023 Yasser Corrales Morales
580  //
581 
582  // Let's start creating the North CYSS Flange
583  // We split the CYSS flange in 2 polycone,
584  // Although it is a single piece.
585  const double sFlgExtThick = 1 * mm;
586  const double sFlgIntThick = 1.5 * mm;
587  const double sFlgSringLen = 4.5 * mm;
588  const double sFlgLringLen = 7.5 * mm;
589  const double sFlgRmin = 23.6 * mm;
590  const double sFlgRmax = 52.8 * mm;
591  const double sFlgSringRmin = 46.4 * mm;
592  const double sFlgSringRmax = 47.4 * mm;
593  const double sFlgLringRmin = 50.6 * mm;
594  const double sFlgLringRmax = 51.5 * mm;
595 
596  const int nZplanes = 4;
597  const double zPlane_1[nZplanes] = {0. * mm,
598  sFlgIntThick,
599  sFlgIntThick,
600  sFlgSringLen};
601 
602  const double rInner_1[nZplanes] = {sFlgRmin,
603  sFlgRmin,
604  sFlgSringRmin,
605  sFlgSringRmin};
606 
607  const double rOuter_1[nZplanes] = {sFlgLringRmin,
608  sFlgLringRmin,
609  sFlgSringRmax,
610  sFlgSringRmax};
611 
612  const double zPlane_2[nZplanes] = {0. * mm,
613  sFlgExtThick,
614  sFlgExtThick,
615  sFlgLringLen};
616 
617  const double rInner_2[nZplanes] = {sFlgLringRmin,
618  sFlgLringRmin,
619  sFlgLringRmin,
620  sFlgLringRmin};
621 
622  const double rOuter_2[nZplanes] = {sFlgRmax,
623  sFlgRmax,
624  sFlgLringRmax,
625  sFlgLringRmax};
626 
627  auto flangeSolid_1 = new G4Polycone("cyssFlangeNorth_1", 0., 2. * M_PI * rad,
628  nZplanes, zPlane_1, rInner_1, rOuter_1);
629 
630  auto flangeSolid_2 = new G4Polycone("cyssFlangeNorth_2", 0., 2. * M_PI * rad,
631  nZplanes, zPlane_2, rInner_2, rOuter_2);
632 
633  auto matAl = PHG4Detector::GetDetectorMaterial("MVTX_EW_Al$");
634 
635  auto cyssFlangeLogVol_1 = new G4LogicalVolume(flangeSolid_1, matAl,
636  "cyssFlangeNorth_1_LOGIC",
637  nullptr, nullptr, nullptr);
638 
639  m_DisplayAction->AddVolume(cyssFlangeLogVol_1, "MVTX_EW_Al$");
640  m_Detector->FillSupportLVArray(cyssFlangeLogVol_1);
641 
642  auto cyssFlangeLogVol_2 = new G4LogicalVolume(flangeSolid_2, matAl,
643  "cyssFlangeNorth_2_LOGIC",
644  nullptr, nullptr, nullptr);
645 
646  m_DisplayAction->AddVolume(cyssFlangeLogVol_2, "MVTX_EW_Al$");
647  m_Detector->FillSupportLVArray(cyssFlangeLogVol_2);
648 
649  double zpos = sEndWheelSNHolesZdist / 2 - (sEndWStepHoleZpos + sEndWStepHoleZdist) + sEndWheelNLen + sFlgIntThick;
650  G4ThreeVector Ta = G4ThreeVector(0., 0., zpos);
651  G4RotationMatrix Ra(0, M_PI * rad, 0.);
652  av->AddPlacedVolume(cyssFlangeLogVol_1, Ta, &Ra);
653  av->AddPlacedVolume(cyssFlangeLogVol_2, Ta, &Ra);
654 
655  // Now we create the CYSS cylinder
656  const double sCYSScylRmax = 52.82 * mm;
657  const double sCYSScylRmin = 51.70 * mm;
658  const double sCYSScylLen = 425.77 * mm;
659 
660  auto cyssCylSol = new G4Tubs("CYSScyl_SOLID", sCYSScylRmin, sCYSScylRmax, sCYSScylLen / 2,
661  0., 2 * M_PI);
662 
663  auto matCF = PHG4Detector::GetDetectorMaterial("MVTX_CarbonFiber$");
664  auto cyssCylLog = new G4LogicalVolume(cyssCylSol, matCF, "CYSScyl_LOGIC",
665  nullptr, nullptr, nullptr);
666  m_DisplayAction->AddVolume(cyssCylLog, "MVTX_CarbonFiber$");
667  m_Detector->FillSupportLVArray(cyssCylLog);
668 
669  zpos -= (sFlgIntThick - sCYSScylLen / 2 + sCYSSFlgSsfFlgNsf - sCYSSFlgSsfCylsf);
670  Ta.set(0., 0., zpos);
671  Ra.set(0, 0., 0.);
672  av->AddPlacedVolume(cyssCylLog, Ta, &Ra);
673 
674  // and the CYSS Cone
675  const double sCYSSconFlgDmin = 106.03 * mm;
676  const double sCYSSconIntDmin = 211.00 * mm;
677  const double sCYSSconFlgThick = 1.12 * mm;
678  const double sCYSSconFlgLen = 13.48 * mm;
679  const double sCYSSconNoseLen = 24.39 * mm;
680  const double sCYSSconThick = 2.16 * mm;
681  const double sCYSSconSlopeLen = 95.0 * mm;
682  const double sCYSSconLen = 200.28 * mm;
683 
684  const int nZplanesCone = 5;
685 
686  const double zPlanesCone[nZplanesCone] = {0 * mm,
687  sCYSSconFlgLen,
688  sCYSSconNoseLen,
689  sCYSSconSlopeLen,
690  sCYSSconLen};
691 
692  const double rInnerCone[nZplanesCone] = {sCYSSconFlgDmin / 2,
693  sCYSSconFlgDmin / 2,
694  sCYSSconFlgDmin / 2,
695  sCYSSconIntDmin / 2,
696  sCYSSconIntDmin / 2};
697 
698  const double rOuterCone[nZplanesCone] = {(sCYSSconFlgDmin + sCYSSconFlgThick) / 2,
699  (sCYSSconFlgDmin + sCYSSconThick) / 2,
700  (sCYSSconFlgDmin + sCYSSconThick) / 2,
701  (sCYSSconIntDmin + sCYSSconThick) / 2,
702  (sCYSSconIntDmin + sCYSSconThick) / 2};
703 
704  auto cyssConeSol = new G4Polycone("cyssConeSol", 0., 2. * M_PI * rad,
705  nZplanesCone, zPlanesCone, rInnerCone, rOuterCone);
706 
707  auto cyssConeLog = new G4LogicalVolume(cyssConeSol, matCF, "CYSScone_LOGIC",
708  nullptr, nullptr, nullptr);
709  m_DisplayAction->AddVolume(cyssConeLog, "MVTX_CarbonFiber$");
710  m_Detector->FillSupportLVArray(cyssConeLog);
711 
712  zpos -= (sCYSScylLen / 2 + sCYSSFlgSsfCylsf - sCYSSconLen - sCYSSFlgSsfConesf);
713  Ta.set(0., 0., zpos);
714  Ra.set(0, M_PI * rad, 0.);
715  av->AddPlacedVolume(cyssConeLog, Ta, &Ra);
716 
717  // Create Rib
718  const double sCYSSribRint = 97.62 * mm;
719  const double sCYSSribRext = 99.32 * mm;
720  const double sCYSSribRmax = 105.30 * mm;
721  const double sCYSSribWidth = 55.23 * mm;
722  const double sCYSSribStep1pos = (15.6 + 7.7) / 2 * mm;
723  const double sCYSSribStep2pos = (47.6 + 39.7) / 2 * mm;
724  const double sCYSSribThick = 1.7 * mm;
725 
726  const int nZplanesRib = 10;
727  const double zPlanesRib[nZplanesRib] = {0. * mm,
728  sCYSSribStep1pos,
729  sCYSSribStep1pos,
730  sCYSSribStep1pos + sCYSSribThick,
731  sCYSSribStep1pos + sCYSSribThick,
732  sCYSSribStep2pos,
733  sCYSSribStep2pos,
734  sCYSSribStep2pos + sCYSSribThick,
735  sCYSSribStep2pos + sCYSSribThick,
736  sCYSSribWidth};
737 
738  const double rInnerRib[nZplanesRib] = {sCYSSribRint,
739  sCYSSribRint,
740  sCYSSribRint,
741  sCYSSribRint,
742  sCYSSribRmax - sCYSSribThick,
743  sCYSSribRmax - sCYSSribThick,
744  sCYSSribRint,
745  sCYSSribRint,
746  sCYSSribRint,
747  sCYSSribRint};
748 
749  const double rOuterRib[nZplanesRib] = {sCYSSribRext,
750  sCYSSribRext,
751  sCYSSribRmax,
752  sCYSSribRmax,
753  sCYSSribRmax,
754  sCYSSribRmax,
755  sCYSSribRmax,
756  sCYSSribRmax,
757  sCYSSribRext,
758  sCYSSribRext};
759 
760  auto cyssRibSol = new G4Polycone("cyssRibSol", 0., 2. * M_PI * rad,
761  nZplanesRib, zPlanesRib, rInnerRib, rOuterRib);
762 
763  auto cyssRibLog = new G4LogicalVolume(cyssRibSol, matCF, "CYSSrib_LOGIC",
764  nullptr, nullptr, nullptr);
765  m_DisplayAction->AddVolume(cyssRibLog, "MVTX_CarbonFiber$");
766  m_Detector->FillSupportLVArray(cyssRibLog);
767 
768  zpos -= (sCYSSconLen + sCYSSFlgSsfConesf - sCYSSFlgSsfRibsf);
769  Ta.set(0., 0., zpos);
770  Ra.set(0, 0., 0.);
771  av->AddPlacedVolume(cyssRibLog, Ta, &Ra);
772 
773  // Flange South
774  const double sFlgSRmax = 107.7 * mm;
775  const double sFlgSRmin = 95.0 * mm;
776  const double sFlgSRstep = 105.3 * mm;
777  const double sFlgSChamfeEnd = 9. * mm;
778  const double sFlgSTotalWidth = 20. * mm;
779  const double sFlgSRimWidth = 7. * mm;
780 
781  const int nZplanesFlgS = 4;
782  const double zPlanesFlgS[nZplanesFlgS] = {0. * mm,
783  sFlgSRimWidth,
784  sFlgSRimWidth,
785  sFlgSTotalWidth};
786 
787  const double rInnerFlgS[nZplanesFlgS] = {sFlgSRmin,
788  sFlgSRmin,
789  sFlgSRmin,
790  sFlgSRstep - sFlgSChamfeEnd};
791 
792  const double rOuterFlgS[nZplanesFlgS] = {sFlgSRmax,
793  sFlgSRmax,
794  sFlgSRstep,
795  sFlgSRstep};
796 
797  auto cyssFlgSSol = new G4Polycone("cyssFlgSSol", 0., 2. * M_PI * rad,
798  nZplanesFlgS, zPlanesFlgS, rInnerFlgS, rOuterFlgS);
799 
800  auto cyssFlgSLog = new G4LogicalVolume(cyssFlgSSol, matAl, "CYSSFlgS_LOGIC",
801  nullptr, nullptr, nullptr);
802  m_DisplayAction->AddVolume(cyssFlgSLog, "MVTX_EW_Al$");
803  m_Detector->FillSupportLVArray(cyssFlgSLog);
804 
805  zpos -= (sCYSSFlgSsfRibsf);
806  Ta.set(0., 0., zpos);
807  Ra.set(0, 0., 0.);
808  av->AddPlacedVolume(cyssFlgSLog, Ta, &Ra);
809 
810  return;
811 }
812 
813 //________________________________________________________________________________
814 void PHG4MvtxSupport::CreateServiceBarrel(G4AssemblyVolume *&av)
815 {
816  //
817  // Creates the ServiceBarrel
818  // (MVTX-2-S-00181)
819  // (MVTX-2-S-00081)
820  //
821  // Input:
822  // av : assembly volume
823  //
824  // Output:
825  //
826  // Return:
827  //
828  //
829  // Created: 21 Jan 2023 Yasser Corrales Morales
830  //
831 
832  // Local Variables
833  double zpos;
834 
835  G4ThreeVector Ta;
836  G4RotationMatrix Ra;
837 
838  // MVTX North SB Flange
839  const double sSBFlgNRmax = 107.7 * mm;
840  const double sSBFlgNRmin = 95.0 * mm;
841  const double sSBFlgNRimRmax = 105.3 * mm;
842  const double sSBFlgNRimRmin = 103.3 * mm;
843  const double sSBFlgNIntThick = 4.92 * mm;
844  const double sSBFlgNExtThick = 7.00 * mm;
845  const double sSBFlgNTotThick = 16.0 * mm;
846 
847  const int nZplanesFlgN = 5;
848  const double zPlanesFlgN[nZplanesFlgN] = {0. * mm,
849  sSBFlgNIntThick,
850  sSBFlgNExtThick,
851  sSBFlgNExtThick,
852  sSBFlgNTotThick};
853 
854  const double rInnerFlgN[nZplanesFlgN] = {sSBFlgNRmin,
855  sSBFlgNRmin,
856  sSBFlgNRimRmin,
857  sSBFlgNRimRmin,
858  sSBFlgNRimRmin};
859 
860  const double rOuterFlgN[nZplanesFlgN] = {sSBFlgNRmax,
861  sSBFlgNRmax,
862  sSBFlgNRmax,
863  sSBFlgNRimRmax,
864  sSBFlgNRimRmax};
865 
866  auto sbFlgNSol = new G4Polycone("sbFlgNSol", 0., 2. * M_PI * rad,
867  nZplanesFlgN, zPlanesFlgN, rInnerFlgN, rOuterFlgN);
868 
869  auto matAl = PHG4Detector::GetDetectorMaterial("MVTX_EW_Al$");
870 
871  auto sbFlgNLog = new G4LogicalVolume(sbFlgNSol, matAl, "sbFlgN_LOGIC",
872  nullptr, nullptr, nullptr);
873  m_DisplayAction->AddVolume(sbFlgNLog, "MVTX_CarbonFiber$");
874  m_Detector->FillSupportLVArray(sbFlgNLog);
875 
877  Ta.set(0., 0., zpos);
878  Ra.set(0, M_PI * rad, 0.);
879  av->AddPlacedVolume(sbFlgNLog, Ta, &Ra);
880 
881  // SB Cylinder (To confirm)
882  const double sSBcylRmin = 105.5 * mm;
883  const double sSBcylRmax = 107.66 * mm;
884  const double sSBcylLen = 1197.0 * mm;
885 
886  auto sbCylSol = new G4Tubs("SBcyl_SOLID", sSBcylRmin, sSBcylRmax,
887  sSBcylLen / 2, 0., 2 * M_PI);
888 
889  auto matCF = PHG4Detector::GetDetectorMaterial("MVTX_CarbonFiber$");
890  auto sbCylLog = new G4LogicalVolume(sbCylSol, matCF, "SBcyl_LOGIC",
891  nullptr, nullptr, nullptr);
892  m_DisplayAction->AddVolume(sbCylLog, "MVTX_CarbonFiber$");
893  m_Detector->FillSupportLVArray(sbCylLog);
894 
895  zpos -= (sSBcylLen / 2 + sSBFlgNExtThick);
896  Ta.set(0., 0., zpos);
897  Ra.set(0, 0., 0.);
898  av->AddPlacedVolume(sbCylLog, Ta, &Ra);
899 
900  return;
901 }
902 
903 //________________________________________________________________________________
904 void PHG4MvtxSupport::CreateCable(PHG4MvtxCable *object, G4AssemblyVolume &assemblyVolume)
905 {
906  std::string cableMaterials[2] = {object->get_coreMaterial(), "G4_POLYETHYLENE"};
907 
908  double dX = object->get_xNorth() - object->get_xSouth();
909  double dY = object->get_yNorth() - object->get_ySouth();
910  double dZ = object->get_zNorth() - object->get_zSouth();
911 
912  double rotY = dZ != 0. ? std::atan(dX / dZ) : 0.;
913  double rotZ = dX != 0. ? std::atan(dY / dX) : 0.;
914 
915  double setX = (object->get_xSouth() + object->get_xNorth()) / 2;
916  double setY = (object->get_ySouth() + object->get_yNorth()) / 2;
917  double setZ = (object->get_zSouth() + object->get_zNorth()) / 2;
918 
919  double length = std::sqrt(dX * dX + dY * dY + dZ * dZ);
920  double IR[2] = {0, object->get_coreRadius()};
921  double OR[2] = {object->get_coreRadius(), object->get_sheathRadius()};
922 
923  G4RotationMatrix rot;
924  rot.rotateY(rotY);
925  rot.rotateZ(rotZ);
926  G4ThreeVector place;
927  place.setX(setX);
928  place.setY(setY);
929  place.setZ(setZ);
930  G4Transform3D transform(rot, place);
931  // we need just one of these but have multiple calls to this method
932  static G4UserLimits *g4userLimits = new G4UserLimits(0.01);
933 
934  for (int i = 0; i < 2; ++i)
935  {
936  G4Material *trackerMaterial = PHG4Detector::GetDetectorMaterial(cableMaterials[i]);
937 
938  G4VSolid *cylinderSolid = new G4Tubs(G4String(object->get_name() + "_SOLID"),
939  IR[i], OR[i], (length / 2.), 0, 2 * M_PI);
940 
941  G4LogicalVolume *cylinderLogic = new G4LogicalVolume(cylinderSolid, trackerMaterial,
942  G4String(object->get_name() + "_LOGIC"), nullptr, nullptr, g4userLimits);
943  m_Detector->FillSupportLVArray(cylinderLogic);
944 
945  if (i == 0)
946  {
947  m_DisplayAction->AddVolume(cylinderLogic, cableMaterials[i]);
948  }
949  else
950  {
951  m_DisplayAction->AddVolume(cylinderLogic, object->get_color());
952  }
953 
954  assemblyVolume.AddPlacedVolume(cylinderLogic, transform);
955  }
956 }
957 
958 //________________________________________________________________________________
959 void PHG4MvtxSupport::CreateCableBundle(G4AssemblyVolume &assemblyVolume, const std::string &superName,
960  bool enableSignal, bool enableCooling, bool enablePower,
961  double x1, double x2, double y1, double y2, double z1, double z2) //, double theta)
962 {
963  // Set up basic MVTX cable bundle (24 Samtec cables, 1 power cable, 2 cooling cables)
964  double samtecCoreRadius = 0.01275 * cm;
965  double samtecSheathRadius = 0.05 * cm;
966  double coolingStaveCoreRadius = 0.056 * cm;
967  double coolingStaveSheathRadius = 0.1 * cm;
968  double coolingCoreRadius = 0.125 * cm;
969  double coolingSheathRadius = 0.2 * cm; //?
970  double powerLargeCoreRadius = 0.069 * cm;
971  double powerLargeSheathRadius = 0.158 * cm;
972  double powerMediumCoreRadius = 0.033 * cm;
973  double powerMediumSheathRadius = 0.082 * cm;
974  double powerSmallCoreRadius = 0.028 * cm;
975  double powerSmallSheathRadius = 0.0573 * cm; //?
976 
977  double globalShiftX = 0.;
978  double globalShiftY = -0.0984 * cm;
979  double samtecShiftX = -6 * samtecSheathRadius + globalShiftX;
980  double samtecShiftY = 1 * samtecSheathRadius + globalShiftY;
981  double coolingShiftX = -3 * coolingSheathRadius + globalShiftX;
982  double coolingShiftY = -1 * coolingSheathRadius + globalShiftY;
983  double powerShiftX = 3.5 * powerLargeSheathRadius + globalShiftX;
984  double powerShiftY = 6.1 * powerLargeSheathRadius + globalShiftY;
985 
986  // Samtec cables (we use 24 as there are 12 twinax)
987  if (enableSignal)
988  {
989  unsigned int nSamtecWires = 24;
990  unsigned int nRow = 8;
991  unsigned int nCol = nSamtecWires / nRow;
992  for (unsigned int iRow = 0; iRow < nRow; ++iRow)
993  {
994  for (unsigned int iCol = 0; iCol < nCol; ++iCol)
995  {
996  double deltaX = samtecShiftX + ((iCol + 1) * (samtecSheathRadius * 2.6));
997  double deltaY = samtecShiftY - ((iRow + 1) * (samtecSheathRadius * 2.1));
998  PHG4MvtxCable *cable = new PHG4MvtxCable(boost::str(boost::format("%s_samtec_%d_%d") % superName.c_str() % iRow % iCol),
999  "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  // Cooling Cables
1009  if (enableCooling)
1010  {
1011  unsigned int nCool = 2;
1012  std::string cooling_color[2] = {"red", "white"};
1013  // std::regex_constants::icase - TO IGNORE CASE.
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  // Power Cables
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 //________________________________________________________________________________
1126 {
1127  G4AssemblyVolume *av = new G4AssemblyVolume();
1128 
1129  CreateCableBundle(*av, "barrelCable", true, true, false, 0, 0, 0, 0,
1131  CreateCableBundle(*av, "barrelCable", false, false, true, 0, 0, 0, 0,
1134  return av;
1135 }
1136 
1137 //________________________________________________________________________________
1138 G4AssemblyVolume *PHG4MvtxSupport::buildLayerCables(const int &lay)
1139 {
1140  G4AssemblyVolume *av = new G4AssemblyVolume();
1141  // double rInner[3] = { 59.94 / 2 * mm, 75.98 / 2 * mm, 91.48 / 2 * mm };
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  // double zTransition2[3] = { -9.186 * cm, -8.938 *cm, -8.538 * cm };
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  // double zCoolStart = - sEndWheelSNHolesZdist / 2 + ( sEndWStepHoleZpos + sEndWStepHoleZdist )
1151  // - 17 * mm - zConeLen[lay];
1152  // CreateCableBundle( *av, Form( "MVTX_L%dCool_0", lay ), false, true, false, rInner[lay], rInner[lay], 0, 0,
1153  // BarrelCableStart, );
1154  // CreateCableBundle(*av, Form( "MVTX_L%dCable_1", lay ), true, false, false, rOuter[lay], rInner[lay], 0, 0, zTransition1[lay] + 0.1, zTransition2[lay]);
1155  // CreateCableBundle(*av, Form( "MVTX_L%dCable_2", lay ), true, false, false, rInner[lay], rInner[lay], 0, 0, zTransition2[lay] + 0.1, zMax);
1156 
1157  return av;
1158 }
1159 
1160 //________________________________________________________________________________
1161 void PHG4MvtxSupport::ConstructMvtxSupport(G4LogicalVolume *&lv)
1162 {
1164  m_avSupport = new G4AssemblyVolume();
1165 
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 
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 }