95 const G4double realTemperture = (273.15 + 23.) * CLHEP::kelvin;
105 G4double h2odensity = 1.000 * CLHEP::g / CLHEP::cm3;
106 G4double a = 1.01 * CLHEP::g / CLHEP::mole;
107 G4Element* elH =
new G4Element(
"Hydrogen",
"H", 1., a);
108 a = 16.00 * CLHEP::g / CLHEP::mole;
109 G4Element* elO =
new G4Element(
"Oxygen",
"O", 8., a);
110 G4Material* medH2O =
new G4Material(
"Water", h2odensity, 2);
111 medH2O->AddElement(elH, 2);
112 medH2O->AddElement(elO, 1);
124 const double num_senseWire =
static_cast<double>(geo.
getNSenseWires());
125 const double num_fieldWire =
static_cast<double>(geo.
getNFieldWires());
126 double totalCS = M_PI * (rmin_outerWall * rmin_outerWall - rmax_innerWall * rmax_innerWall);
129 double senseCS = M_PI * (diameter_senseWire / 2) * (diameter_senseWire / 2) * num_senseWire;
132 double fieldCS = M_PI * (diameter_fieldWire / 2) * (diameter_fieldWire / 2) * num_fieldWire;
135 const double denHelium = medHelium->GetDensity() / 2.0;
136 const double denEthane = medEthane->GetDensity() / 2.0;
137 const double denAluminum = medAluminum->GetDensity() * (fieldCS / totalCS);
138 const double denTungsten = medTungsten->GetDensity() * (senseCS / totalCS);
139 const double density = denHelium + denEthane + denAluminum + denTungsten;
140 G4Material* cdcMed =
new G4Material(
"CDCGasWire", density, 4, kStateGas, realTemperture);
141 cdcMed->AddMaterial(medHelium, denHelium / density);
142 cdcMed->AddMaterial(medEthane, denEthane / density);
143 cdcMed->AddMaterial(medTungsten, denTungsten / density);
144 cdcMed->AddMaterial(medAluminum, denAluminum / density);
146 G4Material* cdcMedGas = cdcMed;
154 const double density2 = denHelium + denEthane;
155 cdcMedGas =
new G4Material(
"CDCRealGas", density2, 2, kStateGas, realTemperture);
156 cdcMedGas->AddMaterial(medHelium, denHelium / density2);
157 cdcMedGas->AddMaterial(medEthane, denEthane / density2);
161 G4cout << *(G4Material::GetMaterialTable());
165 const auto& motherRmin = mother.
getRmin();
166 const auto& motherRmax = mother.getRmax();
167 const auto& motherZ = mother.getZ();
168 G4Polycone* solid_cdc =
169 new G4Polycone(
"solidCDC", 0 * CLHEP::deg, 360.* CLHEP::deg,
170 mother.getNNodes(), motherZ.data(),
171 motherRmin.data(), motherRmax.data());
172 m_logicalCDC =
new G4LogicalVolume(solid_cdc, medAir,
"logicalCDC", 0, 0, 0);
176 "physicalCDC", &topVolume,
false, 0);
179 G4Region* aRegion =
new G4Region(
"CDCEnvelope");
183 m_VisAttributes.push_back(
new G4VisAttributes(
true, G4Colour(0., 1., 0.)));
185 const int iOuterWall = wall.getId();
186 const string wallName = wall.getName();
187 const double wallRmin = wall.getRmin();
188 const double wallRmax = wall.getRmax();
189 const double wallZfwd = wall.getZfwd();
190 const double wallZbwd = wall.getZbwd();
191 const double length = (wallZfwd - wallZbwd) / 2.0;
195 if (strstr((wallName).c_str(),
"MiddleWall") !=
nullptr) {
198 medWall = medAluminum;
200 G4Tubs* outerWallTubeShape =
new G4Tubs(
"solid" + wallName, wallRmin * CLHEP::cm,
201 wallRmax * CLHEP::cm, length * CLHEP::cm, 0 * CLHEP::deg, 360.*CLHEP::deg);
203 G4LogicalVolume* outerWallTube =
new G4LogicalVolume(outerWallTubeShape, medWall,
"solid" + wallName, 0, 0, 0);
205 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (length + wallZbwd)*CLHEP::cm), outerWallTube,
"logical" + wallName,
210 m_VisAttributes.push_back(
new G4VisAttributes(
true, G4Colour(0., 1., 0.)));
212 const string wallName = wall.getName();
213 const double wallRmin = wall.getRmin();
214 const double wallRmax = wall.getRmax();
215 const double wallZfwd = wall.getZfwd();
216 const double wallZbwd = wall.getZbwd();
217 const double length = (wallZfwd - wallZbwd) / 2.0;
218 const int iInnerWall = wall.getId();
221 if (strstr(wallName.c_str(),
"MiddleWall") !=
nullptr) {
223 }
else if (strstr(wallName.c_str(),
"MiddleGlue") !=
nullptr) {
226 medWall = medAluminum;
229 G4Tubs* innerWallTubeShape =
new G4Tubs(
"solid" + wallName, wallRmin * CLHEP::cm,
230 wallRmax * CLHEP::cm, length * CLHEP::cm, 0 * CLHEP::deg, 360.*CLHEP::deg);
231 G4LogicalVolume* innerWallTube =
new G4LogicalVolume(innerWallTubeShape, medWall,
"logical" + wallName, 0, 0, 0);
233 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (length + wallZbwd)*CLHEP::cm), innerWallTube,
"physical" + wallName,
246 for (uint iSLayer = 0; iSLayer < nSLayer; ++iSLayer) {
248 double rmin_sensitive_left, rmax_sensitive_left;
249 double rmin_sensitive_middle, rmax_sensitive_middle;
250 double rmin_sensitive_right, rmax_sensitive_right;
251 double zback_sensitive_left, zfor_sensitive_left;
252 double zback_sensitive_middle, zfor_sensitive_middle;
253 double zback_sensitive_right, zfor_sensitive_right;
256 rmin_sensitive_left, rmax_sensitive_left, zback_sensitive_left, zfor_sensitive_left,
257 rmin_sensitive_middle, rmax_sensitive_middle, zback_sensitive_middle, zfor_sensitive_middle,
258 rmin_sensitive_right, rmax_sensitive_right, zback_sensitive_right, zfor_sensitive_right)) {
263 if ((zfor_sensitive_left - zback_sensitive_left) > length_feedthrough) {
280 G4Tubs* leftTubeShape =
new G4Tubs((boost::format(
"solidCDCLayer_%1%_leftTube") % iSLayer).str().c_str(),
281 rmin_sensitive_left * CLHEP::cm,
282 rmax_sensitive_left * CLHEP::cm, length_feedthrough * CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
283 G4LogicalVolume* leftTube =
new G4LogicalVolume(leftTubeShape, cdcMed,
284 (boost::format(
"logicalCDCLayer_%1%_leftTube") % iSLayer).str().c_str(), 0, 0, 0);
285 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zback_sensitive_left + length_feedthrough / 2.0)*CLHEP::cm), leftTube,
286 (boost::format(
"physicalCDCLayer_%1%_leftTube") % iSLayer).str().c_str(),
m_logicalCDC,
false, iSLayer);
288 G4Tubs* leftSensitiveTubeShape =
new G4Tubs((boost::format(
"solidSD_CDCLayer_%1%_left") % iSLayer).str().c_str(),
289 rmin_sensitive_left * CLHEP::cm, rmax_sensitive_left * CLHEP::cm,
290 (zfor_sensitive_left - zback_sensitive_left - length_feedthrough)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
291 G4LogicalVolume* leftSensitiveTube =
new G4LogicalVolume(leftSensitiveTubeShape, cdcMed,
292 (boost::format(
"logicalSD_CDCLayer_%1%_left") % iSLayer).str().c_str(), 0, 0, 0);
293 leftSensitiveTube->SetSensitiveDetector(
m_sensitive);
294 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfor_sensitive_left + zback_sensitive_left + length_feedthrough)*CLHEP::cm / 2.0),
295 leftSensitiveTube, (boost::format(
"physicalSD_CDCLayer_%1%_left") % iSLayer).str().c_str(),
m_logicalCDC,
false, iSLayer);
313 G4Tubs* leftTubeShape =
new G4Tubs((boost::format(
"solidCDCLayer_%1%_leftTube") % iSLayer).str().c_str(),
314 rmin_sensitive_left * CLHEP::cm,
315 rmax_sensitive_left * CLHEP::cm, (zfor_sensitive_left - zback_sensitive_left)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
316 G4LogicalVolume* leftTube =
new G4LogicalVolume(leftTubeShape, cdcMed,
317 (boost::format(
"logicalCDCLayer_%1%_leftTube") % iSLayer).str().c_str(), 0, 0, 0);
318 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfor_sensitive_left + zback_sensitive_left)*CLHEP::cm / 2.0), leftTube,
319 (boost::format(
"physicalCDCLayer_%1%_leftTube") % iSLayer).str().c_str(),
m_logicalCDC,
false, iSLayer);
323 G4Tubs* leftMidTubeShape =
new G4Tubs((boost::format(
"solidCDCLayer_%1%_leftMidTube") % iSLayer).str().c_str(),
324 rmin_sensitive_middle * CLHEP::cm, rmax_sensitive_middle * CLHEP::cm,
325 (length_feedthrough - zfor_sensitive_left + zback_sensitive_left)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
326 G4LogicalVolume* leftMidTube =
new G4LogicalVolume(leftMidTubeShape, cdcMed,
327 (boost::format(
"logicalCDCLayer_%1%_leftMidTube") % iSLayer).str().c_str(), 0, 0, 0);
329 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (length_feedthrough + zfor_sensitive_left + zback_sensitive_left)*CLHEP::cm / 2.0),
330 leftMidTube, (boost::format(
"physicalCDCLayer_%1%_leftMidTube") % iSLayer).str().c_str(),
m_logicalCDC,
false, iSLayer);
333 zback_sensitive_middle = length_feedthrough + zback_sensitive_left;
337 if ((zfor_sensitive_right - zback_sensitive_right) > length_feedthrough) {
354 G4Tubs* rightTubeShape =
new G4Tubs((boost::format(
"solidCDCLayer_%1%_rightTube") % iSLayer).str().c_str(),
355 rmin_sensitive_right * CLHEP::cm, rmax_sensitive_right * CLHEP::cm, length_feedthrough * CLHEP::cm / 2.0, 0 * CLHEP::deg,
357 G4LogicalVolume* rightTube =
new G4LogicalVolume(rightTubeShape, cdcMed,
358 (boost::format(
"logicalCDCLayer_%1%_rightTube") % iSLayer).str().c_str(), 0, 0, 0);
360 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfor_sensitive_right - length_feedthrough / 2.0)*CLHEP::cm), rightTube,
361 (boost::format(
"physicalCDCLayer_%1%_rightTube") % iSLayer).str().c_str(),
m_logicalCDC,
false, iSLayer);
365 G4Tubs* rightSensitiveTubeShape =
new G4Tubs((boost::format(
"solidSD_CDCLayer_%1%_right") % iSLayer).str().c_str(),
366 rmin_sensitive_right * CLHEP::cm, rmax_sensitive_right * CLHEP::cm,
367 (zfor_sensitive_right - zback_sensitive_right - length_feedthrough)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
368 G4LogicalVolume* rightSensitiveTube =
new G4LogicalVolume(rightSensitiveTubeShape, cdcMed,
369 (boost::format(
"logicalSD_CDCLayer_%1%_right") % iSLayer).str().c_str(), 0, 0, 0);
370 rightSensitiveTube->SetSensitiveDetector(
m_sensitive);
372 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfor_sensitive_right + zback_sensitive_right - length_feedthrough)*CLHEP::cm / 2.0),
373 rightSensitiveTube, (boost::format(
"physicalSD_CDCLayer_%1%_right") % iSLayer).str().c_str(),
m_logicalCDC,
false, iSLayer);
392 G4Tubs* rightTubeShape =
new G4Tubs((boost::format(
"solidCDCLayer_%1%_rightTube") % iSLayer).str().c_str(),
393 rmin_sensitive_right * CLHEP::cm, rmax_sensitive_right * CLHEP::cm, (zfor_sensitive_right - zback_sensitive_right)*CLHEP::cm / 2.0,
394 0 * CLHEP::deg, 360.*CLHEP::deg);
395 G4LogicalVolume* rightTube =
new G4LogicalVolume(rightTubeShape, cdcMed,
396 (boost::format(
"logicalCDCLayer_%1%_rightTube") % iSLayer).str().c_str(), 0, 0, 0);
398 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfor_sensitive_right + zback_sensitive_right)*CLHEP::cm / 2.0), rightTube,
399 (boost::format(
"physicalCDCLayer_%1%_rightTube") % iSLayer).str().c_str(),
m_logicalCDC,
false, iSLayer);
403 G4Tubs* rightMidTubeShape =
new G4Tubs((boost::format(
"solidCDCLayer_%1%_rightMidTube") % iSLayer).str().c_str(),
404 rmin_sensitive_middle * CLHEP::cm, rmax_sensitive_middle * CLHEP::cm,
405 (length_feedthrough - zfor_sensitive_right + zback_sensitive_right)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
406 G4LogicalVolume* rightMidTube =
new G4LogicalVolume(rightMidTubeShape, cdcMed,
407 (boost::format(
"logicalCDCLayer_%1%_rightMidTube") % iSLayer).str().c_str(), 0, 0, 0);
408 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zback_sensitive_right - length_feedthrough + zfor_sensitive_right)*CLHEP::cm / 2.0),
409 rightMidTube, (boost::format(
"physicalCDCLayer_%1%_rightMidTube") % iSLayer).str().c_str(),
m_logicalCDC,
false, iSLayer);
412 zfor_sensitive_middle = zfor_sensitive_right - length_feedthrough;
417 G4Tubs* middleSensitiveTubeShape =
new G4Tubs((boost::format(
"solidSD_CDCLayer_%1%_middle") % iSLayer).str().c_str(),
418 rmin_sensitive_middle * CLHEP::cm, rmax_sensitive_middle * CLHEP::cm,
419 (zfor_sensitive_middle - zback_sensitive_middle)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
420 G4LogicalVolume* middleSensitiveTube =
new G4LogicalVolume(middleSensitiveTubeShape, cdcMedGas,
421 (boost::format(
"logicalSD_CDCLayer_%1%_middle") % iSLayer).str().c_str(), 0, 0, 0);
424 G4UserLimits* uLimits =
new G4UserLimits(8.5 * CLHEP::cm);
426 middleSensitiveTube->SetUserLimits(uLimits);
427 middleSensitiveTube->SetSensitiveDetector(
m_sensitive);
429 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfor_sensitive_middle + zback_sensitive_middle)*CLHEP::cm / 2.0), middleSensitiveTube,
430 (boost::format(
"physicalSD_CDCLayer_%1%_middle") % iSLayer).str().c_str(),
m_logicalCDC,
false, iSLayer);
434 G4String sName =
"sWire";
439 G4double tAtZ0 = -wb0.
Z() / (wf0.
Z() - wb0.
Z());
442 const G4double epsl = 25.e-4;
443 G4double reductionBwd = (zback_sensitive_middle + epsl) / wb0.
Z();
445 wb0 = reductionBwd * (wb0 - wAtZ0) + wAtZ0;
447 G4double reductionFwd = (zfor_sensitive_middle - epsl) / wf0.
Z();
448 wf0 = reductionFwd * (wf0 - wAtZ0) + wAtZ0;
450 const G4double wireHalfLength = 0.5 * (wf0 - wb0).Mag() * CLHEP::cm;
453 G4Tubs* middleSensitiveSwireShape =
new G4Tubs(sName, 0., sWireRadius, wireHalfLength, 0., 360. * CLHEP::deg);
454 G4LogicalVolume* middleSensitiveSwire =
new G4LogicalVolume(middleSensitiveSwireShape, medTungsten, sName);
458 G4String fName =
"fWire";
460 G4Tubs* middleSensitiveFwireShape =
new G4Tubs(fName, 0., fWireRadius, wireHalfLength, 0., 360. * CLHEP::deg);
461 G4LogicalVolume* middleSensitiveFwire =
new G4LogicalVolume(middleSensitiveFwireShape, medAluminum, fName);
468 const G4double dphi = M_PI / nCells;
471 for (
int ic = 0; ic < nCells; ++ic) {
475 G4double tAtZ02 = -wb.
Z() / (wf.
Z() - wb.
Z());
477 G4double reductionBwd2 = (zback_sensitive_middle + epsl) / wb.
Z();
478 wb = reductionBwd2 * (wb - wAtZ02) + wAtZ02;
479 G4double reductionFwd2 = (zfor_sensitive_middle - epsl) / wf.
Z();
480 wf = reductionFwd2 * (wf - wAtZ02) + wAtZ02;
482 G4double thetaYZ = -asin((wf - wb).Y() / (wf - wb).Mag());
484 B2Vector3D fMinusBInZX((wf - wb).X(), 0., (wf - wb).Z());
485 G4double thetaZX = asin((unitZ.
Cross(fMinusBInZX)).Y() / fMinusBInZX.
Mag());
486 G4RotationMatrix rotM;
488 rotM.rotateX(thetaYZ * CLHEP::rad);
489 rotM.rotateY(thetaZX * CLHEP::rad);
491 G4ThreeVector xyz(0.5 * (wb.
X() + wf.
X()) * CLHEP::cm,
492 0.5 * (wb.
Y() + wf.
Y()) * CLHEP::cm, 0.);
496 new G4PVPlacement(G4Transform3D(rotM, xyz), middleSensitiveSwire, sName, middleSensitiveTube,
false, ic);
500 G4double rF = rmax_sensitive_middle - 0.5 * diameter;
502 G4double phi = atan2(wbF.
Y(), wbF.
X());
503 wbF.
SetX(rF * cos(phi));
504 wbF.
SetY(rF * sin(phi));
507 phi = atan2(wfF.
Y(), wfF.
X());
508 wfF.
SetX(rF * cos(phi));
509 wfF.
SetY(rF * sin(phi));
511 thetaYZ = -asin((wfF - wbF).Y() / (wfF - wbF).Mag());
513 fMinusBInZX = wfF - wbF;
514 fMinusBInZX.
SetY(0.);
515 thetaZX = asin((unitZ.
Cross(fMinusBInZX)).Y() / fMinusBInZX.
Mag());
517 G4RotationMatrix rotM1;
518 rotM1.rotateX(thetaYZ * CLHEP::rad);
519 rotM1.rotateY(thetaZX * CLHEP::rad);
521 xyz.setX(0.5 * (wbF.
X() + wfF.
X()) * CLHEP::cm);
522 xyz.setY(0.5 * (wbF.
Y() + wfF.
Y()) * CLHEP::cm);
524 if (iSLayer != nSLayer - 1) {
526 new G4PVPlacement(G4Transform3D(rotM1, xyz), middleSensitiveFwire, fName, middleSensitiveTube,
false, ic);
532 phi = atan2(wbF.
Y(), wbF.
X());
533 wbF.
SetX(rF * cos(phi + dphi));
534 wbF.
SetY(rF * sin(phi + dphi));
538 phi = atan2(wfF.
Y(), wfF.
X());
539 wfF.
SetX(rF * cos(phi + dphi));
540 wfF.
SetY(rF * sin(phi + dphi));
542 thetaYZ = -asin((wfF - wbF).Y() / (wfF - wbF).Mag());
544 fMinusBInZX = wfF - wbF;
545 fMinusBInZX.
SetY(0.);
546 thetaZX = asin((unitZ.
Cross(fMinusBInZX)).Y() / fMinusBInZX.
Mag());
548 G4RotationMatrix rotM2;
549 rotM2.rotateX(thetaYZ * CLHEP::rad);
550 rotM2.rotateY(thetaZX * CLHEP::rad);
552 xyz.setX(0.5 * (wbF.
X() + wfF.
X()) * CLHEP::cm);
553 xyz.setY(0.5 * (wbF.
Y() + wfF.
Y()) * CLHEP::cm);
556 new G4PVPlacement(G4Transform3D(rotM2, xyz), middleSensitiveFwire, fName, middleSensitiveTube,
false, ic + nCells);
560 rF = rmax_sensitive_middle - 0.5 * diameter;
561 phi = atan2(wbF.
Y(), wbF.
X());
562 wbF.
SetX(rF * cos(phi + dphi));
563 wbF.
SetY(rF * sin(phi + dphi));
566 phi = atan2(wfF.
Y(), wfF.
X());
567 wfF.
SetX(rF * cos(phi + dphi));
568 wfF.
SetY(rF * sin(phi + dphi));
570 thetaYZ = -asin((wfF - wbF).Y() / (wfF - wbF).Mag());
572 fMinusBInZX = wfF - wbF;
573 fMinusBInZX.
SetY(0.);
574 thetaZX = asin((unitZ.
Cross(fMinusBInZX)).Y() / fMinusBInZX.
Mag());
576 G4RotationMatrix rotM3;
577 rotM3.rotateX(thetaYZ * CLHEP::rad);
578 rotM3.rotateY(thetaZX * CLHEP::rad);
580 xyz.setX(0.5 * (wbF.
X() + wfF.
X()) * CLHEP::cm);
581 xyz.setY(0.5 * (wbF.
Y() + wfF.
Y()) * CLHEP::cm);
583 if (iSLayer != nSLayer - 1) {
584 new G4PVPlacement(G4Transform3D(rotM3, xyz), middleSensitiveFwire, fName, middleSensitiveTube,
false, ic + 2 * nCells);
594 m_VisAttributes.push_back(
new G4VisAttributes(
true, G4Colour(1., 1., 0.)));
596 for (
const auto& epLayer : endplate.getEndPlateLayers()) {
597 const int iEPLayer = epLayer.getILayer();
598 const string name = epLayer.getName();
599 const double rmin = epLayer.getRmin();
600 const double rmax = epLayer.getRmax();
601 const double zbwd = epLayer.getZbwd();
602 const double zfwd = epLayer.getZfwd();
603 const double length = (zfwd - zbwd) / 2.0;
605 G4Tubs* tube =
new G4Tubs(
"solidCDCEndplate" + name, rmin * CLHEP::cm,
606 rmax * CLHEP::cm, length * CLHEP::cm, 0 * CLHEP::deg, 360.*CLHEP::deg);
607 G4LogicalVolume* logical =
new G4LogicalVolume(tube,
Materials::get(
"G4_Al"),
608 "logicalCDCEndplate" + name, 0, 0);
610 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfwd + zbwd)*CLHEP::cm / 2.0), logical,
611 "physicalCDCEndplate" + name,
m_logicalCDC,
false, iEPLayer);
620 const int iEB = frontend.getId();
621 const double ebInnerR = frontend.getRmin();
622 const double ebOuterR = frontend.getRmax();
623 const double ebBZ = frontend.getZbwd();
624 const double ebFZ = frontend.getZfwd();
626 G4Tubs* ebTubeShape =
new G4Tubs((boost::format(
"solidSD_ElectronicsBoard_Layer%1%") % iEB).str().c_str(), ebInnerR * CLHEP::cm,
627 ebOuterR * CLHEP::cm, (ebFZ - ebBZ)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
629 G4LogicalVolume* ebTube =
new G4LogicalVolume(ebTubeShape, medNEMA_G10_Plate,
630 (boost::format(
"logicalSD_ElectronicsBoard_Layer%1%") % iEB).str().c_str(), 0, 0, 0);
634 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (ebFZ + ebBZ)*CLHEP::cm / 2.0), ebTube,
635 (boost::format(
"physicalSD_ElectronicsBoard_Layer%1%") % iEB).str().c_str(),
m_logicalCDC,
false, iEB);
656 for (
const auto& rib : geo.
getRibs()) {
658 const int id = rib.getId();
659 const double length = rib.getLength();
660 const double width = rib.getWidth();
661 const double thick = rib.getThick();
662 const double rotx = rib.getRotX();
663 const double roty = rib.getRotY();
664 const double rotz = rib.getRotZ();
665 const double x = rib.getX();
666 const double y = rib.getY();
667 const double z = rib.getZ();
668 const int offset = rib.getOffset();
669 const int ndiv = rib.getNDiv();
671 const string solidName =
"solidRib" + to_string(
id);
672 const string logicalName =
"logicalRib" + to_string(
id);
673 G4Box* boxShape =
new G4Box(solidName, 0.5 * length * CLHEP::cm,
674 0.5 * width * CLHEP::cm,
675 0.5 * thick * CLHEP::cm);
677 const double rmax = 0.5 * length;
678 const double rmin = max((rmax - thick), 0.);
679 G4Tubs* tubeShape =
new G4Tubs(solidName,
682 0.5 * width * CLHEP::cm,
689 G4LogicalVolume* logicalV =
new G4LogicalVolume(boxShape, medAluminum, logicalName, 0, 0, 0);
690 if (
id > 39 &&
id < 78)
691 logicalV =
new G4LogicalVolume(boxShape, medCopper, logicalName, 0, 0, 0);
692 if ((
id > 77 &&
id < 94) || (
id > 131 &&
id < 146))
693 logicalV =
new G4LogicalVolume(boxShape, medNEMA_G10_Plate, logicalName, 0, 0, 0);
694 if (
id > 93 &&
id < 110)
695 logicalV =
new G4LogicalVolume(tubeShape, medCopper, logicalName, 0, 0, 0);
696 if (
id > 109 &&
id < 126)
697 logicalV =
new G4LogicalVolume(tubeShape, medH2O, logicalName, 0, 0, 0);
698 if (
id > 127 &&
id < 132)
699 logicalV =
new G4LogicalVolume(boxShape, medHV, logicalName, 0, 0, 0);
709 const double phi = 360.0 / ndiv;
711 G4RotationMatrix rot = G4RotationMatrix();
713 if (
id > 93 &&
id < 126) dz = 0;
715 G4ThreeVector arm(x * CLHEP::cm, y * CLHEP::cm, z * CLHEP::cm - dz * CLHEP::cm / 2.0);
720 rot.rotateZ(0.5 * phi * CLHEP::deg);
721 arm.rotateZ(0.5 * phi * CLHEP::deg);
723 for (
int i = 0; i < ndiv; ++i) {
724 const string physicalName =
"physicalRib_" + to_string(
id) +
" " + to_string(i);
725 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
727 rot.rotateZ(phi * CLHEP::deg);
728 arm.rotateZ(phi * CLHEP::deg);
736 for (
const auto& rib2 : geo.
getRib2s()) {
738 const int id = rib2.getId();
739 const double length = rib2.getLength();
740 const double width = rib2.getWidth();
741 const double thick = rib2.getThick();
742 const double width2 = rib2.getWidth2();
743 const double thick2 = rib2.getThick2();
744 const double rotx = rib2.getRotX();
745 const double roty = rib2.getRotY();
746 const double rotz = rib2.getRotZ();
747 const double x = rib2.getX();
748 const double y = rib2.getY();
749 const double z = rib2.getZ();
750 const int ndiv = rib2.getNDiv();
752 const string solidName =
"solidRib2" + to_string(
id);
753 const string logicalName =
"logicalRib2" + to_string(
id);
754 G4Trd* trdShape =
new G4Trd(solidName,
755 0.5 * thick * CLHEP::cm,
756 0.5 * thick2 * CLHEP::cm,
757 0.5 * width * CLHEP::cm,
758 0.5 * width2 * CLHEP::cm,
759 0.5 * length * CLHEP::cm);
761 G4LogicalVolume* logicalV =
new G4LogicalVolume(trdShape, medAluminum, logicalName, 0, 0, 0);
764 logicalV =
new G4LogicalVolume(trdShape, medCopper, logicalName, 0, 0, 0);
768 const double phi = 360.0 / ndiv;
770 G4RotationMatrix rot = G4RotationMatrix();
771 G4ThreeVector arm(x * CLHEP::cm, y * CLHEP::cm, z * CLHEP::cm - thick * CLHEP::cm / 2.0);
776 for (
int i = 0; i < ndiv; ++i) {
777 const string physicalName =
"physicalRib2_" + to_string(
id) +
" " + to_string(i);
778 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
780 rot.rotateZ(phi * CLHEP::deg);
781 arm.rotateZ(phi * CLHEP::deg);
789 for (
const auto& rib3 : geo.
getRib3s()) {
791 const int id = rib3.getId();
792 const double length = rib3.getLength();
793 const double width = rib3.getWidth();
794 const double thick = rib3.getThick();
795 const double r = rib3.getR();
796 const double x = rib3.getX();
797 const double y = rib3.getY();
798 const double z = rib3.getZ();
799 const double rx = rib3.getRx();
800 const double ry = rib3.getRy();
801 const double rz = rib3.getRz();
802 const int offset = rib3.getOffset();
803 const int ndiv = rib3.getNDiv();
805 const string logicalName =
"logicalRib3" + to_string(
id);
806 G4VSolid* boxShape =
new G4Box(
"Block",
807 0.5 * length * CLHEP::cm,
808 0.5 * width * CLHEP::cm,
809 0.5 * thick * CLHEP::cm);
810 G4VSolid* tubeShape =
new G4Tubs(
"Hole",
817 G4RotationMatrix rotsub = G4RotationMatrix();
818 rotsub.rotateX(90. * CLHEP::deg);
819 G4ThreeVector trnsub(rx * CLHEP::cm - x * CLHEP::cm, ry * CLHEP::cm - y * CLHEP::cm,
820 rz * CLHEP::cm - z * CLHEP::cm + 0.5 * thick * CLHEP::cm);
821 G4VSolid* coolingBlock =
new G4SubtractionSolid(
"Block-Hole",
824 G4Transform3D(rotsub,
827 G4LogicalVolume* logicalV =
new G4LogicalVolume(coolingBlock, medCopper, logicalName, 0, 0, 0);
831 const double phi = 360.0 / ndiv;
833 G4RotationMatrix rot = G4RotationMatrix();
834 G4ThreeVector arm(x * CLHEP::cm, y * CLHEP::cm, z * CLHEP::cm - thick * CLHEP::cm / 2.0);
837 rot.rotateZ(0.5 * phi * CLHEP::deg);
838 arm.rotateZ(0.5 * phi * CLHEP::deg);
840 for (
int i = 0; i < ndiv; ++i) {
841 const string physicalName =
"physicalRib3_" + to_string(
id) +
" " + to_string(i);
842 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
844 rot.rotateZ(phi * CLHEP::deg);
845 arm.rotateZ(phi * CLHEP::deg);
853 for (
const auto& rib4 : geo.
getRib4s()) {
855 const int id = rib4.getId();
856 const double length = rib4.getLength();
857 const double width = rib4.getWidth();
858 const double thick = rib4.getThick();
859 const double length2 = rib4.getLength2();
860 const double width2 = rib4.getWidth2();
861 const double thick2 = rib4.getThick2();
862 const double x = rib4.getX();
863 const double y = rib4.getY();
864 const double z = rib4.getZ();
865 const double x2 = rib4.getX2();
866 const double y2 = rib4.getY2();
867 const double z2 = rib4.getZ2();
868 const int offset = rib4.getOffset();
869 const int ndiv = rib4.getNDiv();
871 const string logicalName =
"logicalRib4" + to_string(
id);
872 G4VSolid* baseShape =
new G4Box(
"Base",
873 0.5 * length * CLHEP::cm,
874 0.5 * width * CLHEP::cm,
875 0.5 * thick * CLHEP::cm);
876 G4VSolid* sqShape =
new G4Box(
"Sq",
877 0.5 * length2 * CLHEP::cm,
878 0.5 * width2 * CLHEP::cm,
879 0.5 * thick2 * CLHEP::cm);
881 G4RotationMatrix rotsub = G4RotationMatrix();
882 double dzc = (z2 - thick2 / 2.) - (z - thick / 2.);
883 G4ThreeVector trnsub(x2 * CLHEP::cm - x * CLHEP::cm,
884 y2 * CLHEP::cm - y * CLHEP::cm,
886 G4VSolid* sqHoleBase =
new G4SubtractionSolid(
"Box-Sq",
889 G4Transform3D(rotsub,
893 G4LogicalVolume* logicalV =
new G4LogicalVolume(sqHoleBase, medCopper, logicalName, 0, 0, 0);
895 logicalV =
new G4LogicalVolume(sqHoleBase, medNEMA_G10_Plate, logicalName, 0, 0, 0);
898 logicalV->SetSensitiveDetector(sensitiveDetector);
904 const double phi = 360.0 / ndiv;
906 G4RotationMatrix rot = G4RotationMatrix();
907 G4ThreeVector arm(x * CLHEP::cm, y * CLHEP::cm, z * CLHEP::cm - thick * CLHEP::cm / 2.0);
910 rot.rotateZ(0.5 * phi * CLHEP::deg);
911 arm.rotateZ(0.5 * phi * CLHEP::deg);
913 for (
int i = 0; i < ndiv; ++i) {
914 const string physicalName =
"physicalRib4_" + to_string(
id) +
" " + to_string(i);
915 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
917 rot.rotateZ(phi * CLHEP::deg);
918 arm.rotateZ(phi * CLHEP::deg);
925 for (
const auto& rib5 : geo.
getRib5s()) {
927 const int id = rib5.getId();
928 const double dr = rib5.getDr();
929 const double dz = rib5.getDz();
930 const double width = rib5.getWidth();
931 const double thick = rib5.getThick();
932 const double rin = rib5.getRin();
933 const double x = rib5.getX();
934 const double y = rib5.getY();
935 const double z = rib5.getZ();
936 const double rotx = rib5.getRotx();
937 const double roty = rib5.getRoty();
938 const double rotz = rib5.getRotz();
939 const int offset = rib5.getOffset();
940 const int ndiv = rib5.getNDiv();
942 const string solidName =
"solidRib5" + to_string(
id);
943 const string logicalName =
"logicalRib5" + to_string(
id);
945 const double rmax = rin + thick;
946 const double rmin = rin;
947 const double dphi = 2. * atan2(dz, dr);
948 const double ddphi = thick *
tan(dphi) / rin;
949 const double ddphi2 = width / 2. * width / 2. / (x + dr) / rin;
950 const double cphi = dphi - ddphi - ddphi2;
951 G4Tubs* tubeShape =
new G4Tubs(solidName,
954 0.5 * width * CLHEP::cm,
958 G4LogicalVolume* logicalV =
new G4LogicalVolume(tubeShape, medAluminum, logicalName, 0, 0, 0);
962 const double phi = 360.0 / ndiv;
964 G4RotationMatrix rot = G4RotationMatrix();
967 G4ThreeVector arm(x * CLHEP::cm, y * CLHEP::cm, z * CLHEP::cm - rin * CLHEP::cm - thick * CLHEP::cm);
972 rot.rotateZ(0.5 * phi * CLHEP::deg);
973 arm.rotateZ(0.5 * phi * CLHEP::deg);
975 for (
int i = 0; i < ndiv; ++i) {
976 const string physicalName =
"physicalRib5_" + to_string(
id) +
" " + to_string(i);
977 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
979 rot.rotateZ(phi * CLHEP::deg);
980 arm.rotateZ(phi * CLHEP::deg);
1092 string Aluminum = content.getString(
"Aluminum");
1095 G4double density = 1.000 * CLHEP::g / CLHEP::cm3;
1096 G4double a = 1.01 * CLHEP::g / CLHEP::mole;
1097 G4Element* elH =
new G4Element(
"Hydrogen",
"H", 1., a);
1098 a = 16.00 * CLHEP::g / CLHEP::mole;
1099 G4Element* elO =
new G4Element(
"Oxygen",
"O", 8., a);
1100 G4Material* medH2O =
new G4Material(
"Water", density, 2);
1101 medH2O->AddElement(elH, 2);
1102 medH2O->AddElement(elO, 1);
1110 m_VisAttributes.push_back(
new G4VisAttributes(
true, G4Colour(0., 1., 0.)));
1111 const int nCover = content.getNumberNodes(
"Covers/Cover");
1112 for (
int iCover = 0; iCover < nCover; ++iCover) {
1113 GearDir coverContent(content);
1114 coverContent.
append((boost::format(
"/Covers/Cover[%1%]/") % (iCover + 1)).str());
1115 const string scoverID = coverContent.
getString(
"@id");
1116 const int coverID = atoi(scoverID.c_str());
1117 const string coverName = coverContent.
getString(
"Name");
1118 const double coverInnerR1 = coverContent.
getLength(
"InnerR1");
1119 const double coverInnerR2 = coverContent.
getLength(
"InnerR2");
1120 const double coverOuterR1 = coverContent.
getLength(
"OuterR1");
1121 const double coverOuterR2 = coverContent.
getLength(
"OuterR2");
1122 const double coverThick = coverContent.
getLength(
"Thickness");
1123 const double coverPosZ = coverContent.
getLength(
"PosZ");
1125 const double rmin1 = coverInnerR1;
1126 const double rmax1 = coverOuterR1;
1127 const double rmin2 = coverInnerR2;
1128 const double rmax2 = coverOuterR2;
1139 if (coverID == 7 || coverID == 10) {
1140 createCone(rmin1, rmax1, rmin2, rmax2, coverThick, coverPosZ, coverID, medAluminum, coverName);
1142 createTube(rmin1, rmax1, coverThick, coverPosZ, coverID, medAluminum, coverName);
1145 if (coverID > 22 && coverID < 29)
1146 createTube(rmin1, rmax1, coverThick, coverPosZ, coverID, medCopper, coverName);
1147 if (coverID > 28 && coverID < 35)
1148 createTorus(rmin1, rmax1, coverThick, coverPosZ, coverID, medCopper, coverName);
1149 if (coverID > 34 && coverID < 41)
1150 createTorus(rmin1, rmax1, coverThick, coverPosZ, coverID, medH2O, coverName);
1151 if (coverID == 45 || coverID == 46)
1152 createTube(rmin1, rmax1, coverThick, coverPosZ, coverID, medLV, coverName);
1153 if (coverID == 47 || coverID == 48)
1154 createTube(rmin1, rmax1, coverThick, coverPosZ, coverID, medFiber, coverName);
1155 if (coverID == 49 || coverID == 50)
1156 createTube(rmin1, rmax1, coverThick, coverPosZ, coverID, medCAT7, coverName);
1157 if (coverID == 51 || coverID == 52)
1158 createTube(rmin1, rmax1, coverThick, coverPosZ, coverID, medTRG, coverName);
1160 createTube(rmin1, rmax1, coverThick, coverPosZ, coverID, medHV, coverName);
1163 const int nCover2 = content.getNumberNodes(
"Covers/Cover2");
1164 for (
int iCover2 = 0; iCover2 < nCover2; ++iCover2) {
1165 GearDir cover2Content(content);
1166 cover2Content.
append((boost::format(
"/Cover2s/Cover2[%1%]/") % (iCover2 + 1)).str());
1167 const string scover2ID = cover2Content.
getString(
"@id");
1168 const int cover2ID = atoi(scover2ID.c_str());
1169 const string cover2Name = cover2Content.
getString(
"Name");
1170 const double cover2InnerR = cover2Content.
getLength(
"InnerR");
1171 const double cover2OuterR = cover2Content.
getLength(
"OuterR");
1172 const double cover2StartPhi = cover2Content.
getLength(
"StartPhi");
1173 const double cover2DeltaPhi = cover2Content.
getLength(
"DeltaPhi");
1174 const double cover2Thick = cover2Content.
getLength(
"Thickness");
1175 const double cover2PosZ = cover2Content.
getLength(
"PosZ");
1178 createTube2(cover2InnerR, cover2OuterR, cover2StartPhi, cover2DeltaPhi, cover2Thick, cover2PosZ, cover2ID, medHV, cover2Name);
1179 if (cover2ID > 10 && cover2ID < 14)
1180 createTube2(cover2InnerR, cover2OuterR, cover2StartPhi, cover2DeltaPhi, cover2Thick, cover2PosZ, cover2ID, medFiber, cover2Name);
1181 if (cover2ID > 13 && cover2ID < 23)
1182 createTube2(cover2InnerR, cover2OuterR, cover2StartPhi, cover2DeltaPhi, cover2Thick, cover2PosZ, cover2ID, medCAT7, cover2Name);
1183 if (cover2ID > 22 && cover2ID < 29)
1184 createTube2(cover2InnerR, cover2OuterR, cover2StartPhi, cover2DeltaPhi, cover2Thick, cover2PosZ, cover2ID, medTRG, cover2Name);
1187 const int nRibs = content.getNumberNodes(
"Covers/Rib");
1188 for (
int iRib = 0; iRib < nRibs; ++iRib) {
1190 ribContent.
append((boost::format(
"/Covers/Rib[%1%]/") % (iRib + 1)).str());
1191 const string sribID = ribContent.
getString(
"@id");
1192 const int ribID = atoi(sribID.c_str());
1194 const double length = ribContent.
getLength(
"Length");
1195 const double width = ribContent.
getLength(
"Width");
1196 const double thick = ribContent.
getLength(
"Thickness");
1197 const double rotX = ribContent.
getLength(
"RotX");
1198 const double rotY = ribContent.
getLength(
"RotY");
1199 const double rotZ = ribContent.
getLength(
"RotZ");
1200 const double cX = ribContent.
getLength(
"PosX");
1201 const double cY = ribContent.
getLength(
"PosY");
1202 const double cZ = ribContent.
getLength(
"PosZ");
1203 const int offset = atoi((ribContent.
getString(
"Offset")).c_str());
1204 const int number = atoi((ribContent.
getString(
"NDiv")).c_str());
1206 const string solidName =
"solidRib" + to_string(ribID);
1207 const string logicalName =
"logicalRib" + to_string(ribID);
1208 G4Box* boxShape =
new G4Box(solidName, 0.5 * length * CLHEP::cm,
1209 0.5 * width * CLHEP::cm,
1210 0.5 * thick * CLHEP::cm);
1211 const double rmax = 0.5 * length;
1212 const double rmin = max((rmax - thick), 0.);
1213 G4Tubs* tubeShape =
new G4Tubs(solidName,
1216 0.5 * width * CLHEP::cm,
1223 G4LogicalVolume* logicalV =
new G4LogicalVolume(boxShape, medAluminum, logicalName, 0, 0, 0);
1224 if (ribID > 39 && ribID < 78)
1225 logicalV =
new G4LogicalVolume(boxShape, medCopper, logicalName, 0, 0, 0);
1226 if ((ribID > 77 && ribID < 94) || (ribID > 131 && ribID < 146))
1227 logicalV =
new G4LogicalVolume(boxShape, medNEMA_G10_Plate, logicalName, 0, 0, 0);
1228 if (ribID > 93 && ribID < 110)
1229 logicalV =
new G4LogicalVolume(tubeShape, medCopper, logicalName, 0, 0, 0);
1230 if (ribID > 109 && ribID < 126)
1231 logicalV =
new G4LogicalVolume(tubeShape, medH2O, logicalName, 0, 0, 0);
1233 if (ribID > 127 && ribID < 132)
1234 logicalV =
new G4LogicalVolume(boxShape, medHV, logicalName, 0, 0, 0);
1244 const double phi = 360.0 / number;
1246 G4RotationMatrix rot = G4RotationMatrix();
1249 if (ribID > 93 && ribID < 126) dz = 0;
1250 G4ThreeVector arm(cX * CLHEP::cm, cY * CLHEP::cm, cZ * CLHEP::cm - dz * CLHEP::cm / 2.0);
1256 rot.rotateZ(0.5 * phi * CLHEP::deg);
1257 arm.rotateZ(0.5 * phi * CLHEP::deg);
1259 for (
int i = 0; i < number; ++i) {
1260 const string physicalName =
"physicalRib_" + to_string(ribID) +
" " + to_string(i);
1261 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
1263 rot.rotateZ(phi * CLHEP::deg);
1264 arm.rotateZ(phi * CLHEP::deg);
1269 const int nRib2s = content.getNumberNodes(
"Covers/Rib2");
1270 for (
int iRib2 = 0; iRib2 < nRib2s; ++iRib2) {
1272 rib2Content.
append((boost::format(
"/Covers/Rib2[%1%]/") % (iRib2 + 1)).str());
1273 const string srib2ID = rib2Content.
getString(
"@id");
1274 const int rib2ID = atoi(srib2ID.c_str());
1276 const double length = rib2Content.
getLength(
"Length");
1277 const double width = rib2Content.
getLength(
"Width");
1278 const double thick = rib2Content.
getLength(
"Thickness");
1279 const double width2 = rib2Content.
getLength(
"Width2");
1280 const double thick2 = rib2Content.
getLength(
"Thickness2");
1281 const double rotX = rib2Content.
getLength(
"RotX");
1282 const double rotY = rib2Content.
getLength(
"RotY");
1283 const double rotZ = rib2Content.
getLength(
"RotZ");
1284 const double cX = rib2Content.
getLength(
"PosX");
1285 const double cY = rib2Content.
getLength(
"PosY");
1286 const double cZ = rib2Content.
getLength(
"PosZ");
1287 const int number = atoi((rib2Content.
getString(
"NDiv")).c_str());
1289 const string solidName =
"solidRib2" + to_string(rib2ID);
1290 const string logicalName =
"logicalRib2" + to_string(rib2ID);
1291 G4Trd* trdShape =
new G4Trd(solidName,
1292 0.5 * thick * CLHEP::cm,
1293 0.5 * thick2 * CLHEP::cm,
1294 0.5 * width * CLHEP::cm,
1295 0.5 * width2 * CLHEP::cm,
1296 0.5 * length * CLHEP::cm);
1298 G4LogicalVolume* logicalV =
new G4LogicalVolume(trdShape, medAluminum, logicalName, 0, 0, 0);
1300 logicalV =
new G4LogicalVolume(trdShape, medCopper, logicalName, 0, 0, 0);
1305 const double phi = 360.0 / number;
1307 G4RotationMatrix rot = G4RotationMatrix();
1308 G4ThreeVector arm(cX * CLHEP::cm, cY * CLHEP::cm, cZ * CLHEP::cm - thick * CLHEP::cm / 2.0);
1313 for (
int i = 0; i < number; ++i) {
1314 const string physicalName =
"physicalRib2_" + to_string(rib2ID) +
" " + to_string(i);
1315 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
1317 rot.rotateZ(phi * CLHEP::deg);
1318 arm.rotateZ(phi * CLHEP::deg);
1323 const int nRib3s = content.getNumberNodes(
"Covers/Rib3");
1324 for (
int iRib3 = 0; iRib3 < nRib3s; ++iRib3) {
1326 rib3Content.
append((boost::format(
"/Covers/Rib3[%1%]/") % (iRib3 + 1)).str());
1327 const string srib3ID = rib3Content.
getString(
"@id");
1328 const int rib3ID = atoi(srib3ID.c_str());
1330 const double length = rib3Content.
getLength(
"Length");
1331 const double width = rib3Content.
getLength(
"Width");
1332 const double thick = rib3Content.
getLength(
"Thickness");
1333 const double r = rib3Content.
getLength(
"HoleR");
1334 const double cX = rib3Content.
getLength(
"PosX");
1335 const double cY = rib3Content.
getLength(
"PosY");
1336 const double cZ = rib3Content.
getLength(
"PosZ");
1337 const double hX = rib3Content.
getLength(
"HoleX");
1338 const double hY = rib3Content.
getLength(
"HoleY");
1339 const double hZ = rib3Content.
getLength(
"HoleZ");
1340 const int offset = atoi((rib3Content.
getString(
"Offset")).c_str());
1341 const int number = atoi((rib3Content.
getString(
"NDiv")).c_str());
1343 const string logicalName =
"logicalRib3" + to_string(rib3ID);
1344 G4VSolid* boxShape =
new G4Box(
"Block",
1345 0.5 * length * CLHEP::cm,
1346 0.5 * width * CLHEP::cm,
1347 0.5 * thick * CLHEP::cm);
1348 G4VSolid* tubeShape =
new G4Tubs(
"Hole",
1354 G4RotationMatrix rotsub = G4RotationMatrix();
1355 G4ThreeVector trnsub(cX * CLHEP::cm - hX * CLHEP::cm, cY * CLHEP::cm - hY * CLHEP::cm,
1356 cZ * CLHEP::cm - hZ * CLHEP::cm + 0.5 * thick * CLHEP::cm);
1357 G4VSolid* coolingBlock =
new G4SubtractionSolid(
"Block-Hole",
1360 G4Transform3D(rotsub,
1363 G4LogicalVolume* logicalV =
new G4LogicalVolume(coolingBlock, medCopper, logicalName, 0, 0, 0);
1367 const double phi = 360.0 / number;
1369 G4RotationMatrix rot = G4RotationMatrix();
1370 G4ThreeVector arm(cX * CLHEP::cm, cY * CLHEP::cm, cZ * CLHEP::cm - thick * CLHEP::cm / 2.0);
1373 rot.rotateZ(0.5 * phi * CLHEP::deg);
1374 arm.rotateZ(0.5 * phi * CLHEP::deg);
1376 for (
int i = 0; i < number; ++i) {
1377 const string physicalName =
"physicalRib3_" + to_string(rib3ID) +
" " + to_string(i);
1378 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
1380 rot.rotateZ(phi * CLHEP::deg);
1381 arm.rotateZ(phi * CLHEP::deg);
1386 const int nRib4s = content.getNumberNodes(
"Covers/Rib4");
1387 for (
int iRib4 = 0; iRib4 < nRib4s; ++iRib4) {
1389 rib4Content.
append((boost::format(
"/Covers/Rib4[%1%]/") % (iRib4 + 1)).str());
1390 const string srib4ID = rib4Content.
getString(
"@id");
1391 const int rib4ID = atoi(srib4ID.c_str());
1393 const double length = rib4Content.
getLength(
"Length");
1394 const double width = rib4Content.
getLength(
"Width");
1395 const double thick = rib4Content.
getLength(
"Thickness");
1396 const double length2 = rib4Content.
getLength(
"Length2");
1397 const double width2 = rib4Content.
getLength(
"Width2");
1398 const double thick2 = rib4Content.
getLength(
"Thickness2");
1399 const double cX = rib4Content.
getLength(
"PosX");
1400 const double cY = rib4Content.
getLength(
"PosY");
1401 const double cZ = rib4Content.
getLength(
"PosZ");
1402 const double hX = rib4Content.
getLength(
"HoleX");
1403 const double hY = rib4Content.
getLength(
"HoleY");
1404 const double hZ = rib4Content.
getLength(
"HoleZ");
1405 const int offset = atoi((rib4Content.
getString(
"Offset")).c_str());
1406 const int number = atoi((rib4Content.
getString(
"NDiv")).c_str());
1408 const string logicalName =
"logicalRib4" + to_string(rib4ID);
1409 G4VSolid* baseShape =
new G4Box(
"Base",
1410 0.5 * length * CLHEP::cm,
1411 0.5 * width * CLHEP::cm,
1412 0.5 * thick * CLHEP::cm);
1413 G4VSolid* sqShape =
new G4Box(
"Sq",
1414 0.5 * length2 * CLHEP::cm,
1415 0.5 * width2 * CLHEP::cm,
1416 0.5 * thick2 * CLHEP::cm);
1417 G4RotationMatrix rotsub = G4RotationMatrix();
1418 double dzc = (hZ - thick2 / 2.) - (cZ - thick / 2.);
1419 G4ThreeVector trnsub(hX * CLHEP::cm - cX * CLHEP::cm,
1420 hY * CLHEP::cm - cY * CLHEP::cm,
1422 G4VSolid* sqHoleBase =
new G4SubtractionSolid(
"Base-Sq",
1425 G4Transform3D(rotsub,
1429 G4LogicalVolume* logicalV =
new G4LogicalVolume(sqHoleBase, medCopper, logicalName, 0, 0, 0);
1431 logicalV =
new G4LogicalVolume(sqHoleBase, medNEMA_G10_Plate, logicalName, 0, 0, 0);
1435 const double phi = 360.0 / number;
1437 G4RotationMatrix rot = G4RotationMatrix();
1438 G4ThreeVector arm(cX * CLHEP::cm, cY * CLHEP::cm, cZ * CLHEP::cm - thick * CLHEP::cm / 2.0);
1441 rot.rotateZ(0.5 * phi * CLHEP::deg);
1442 arm.rotateZ(0.5 * phi * CLHEP::deg);
1444 for (
int i = 0; i < number; ++i) {
1445 const string physicalName =
"physicalRib4_" + to_string(rib4ID) +
" " + to_string(i);
1446 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
1448 rot.rotateZ(phi * CLHEP::deg);
1449 arm.rotateZ(phi * CLHEP::deg);
1454 const int nRib5s = content.getNumberNodes(
"Covers/Rib5");
1455 for (
int iRib5 = 0; iRib5 < nRib5s; ++iRib5) {
1457 rib5Content.
append((boost::format(
"/Covers/Rib5[%1%]/") % (iRib5 + 1)).str());
1458 const string srib5ID = rib5Content.
getString(
"@id");
1459 const int rib5ID = atoi(srib5ID.c_str());
1461 const double dr = rib5Content.
getLength(
"DeltaR");
1462 const double dz = rib5Content.
getLength(
"DeltaZ");
1463 const double width = rib5Content.
getLength(
"Width");
1464 const double thick = rib5Content.
getLength(
"Thickness");
1465 const double rin = rib5Content.
getLength(
"Rin");
1466 const double rotX = rib5Content.
getLength(
"RotX");
1467 const double rotY = rib5Content.
getLength(
"RotY");
1468 const double rotZ = rib5Content.
getLength(
"RotZ");
1469 const double cX = rib5Content.
getLength(
"PosX");
1470 const double cY = rib5Content.
getLength(
"PosY");
1471 const double cZ = rib5Content.
getLength(
"PosZ");
1472 const int offset = atoi((rib5Content.
getString(
"Offset")).c_str());
1473 const int number = atoi((rib5Content.
getString(
"NDiv")).c_str());
1475 const string solidName =
"solidRib5" + to_string(rib5ID);
1476 const string logicalName =
"logicalRib5" + to_string(rib5ID);
1477 const double rmax = rin + thick;
1478 const double rmin = rin;
1479 const double dphi = 2. * atan2(dz, dr);
1480 const double ddphi = thick *
tan(dphi) / rin;
1481 const double ddphi2 = width / 2. * width / 2. / (cX + dr) / rin;
1482 const double cphi = dphi - ddphi - ddphi2;
1483 G4Tubs* tubeShape =
new G4Tubs(solidName,
1486 0.5 * width * CLHEP::cm,
1490 G4LogicalVolume* logicalV =
new G4LogicalVolume(tubeShape, medAluminum, logicalName, 0, 0, 0);
1494 const double phi = 360.0 / number;
1496 G4RotationMatrix rot = G4RotationMatrix();
1499 G4ThreeVector arm(cX * CLHEP::cm, cY * CLHEP::cm, cZ * CLHEP::cm - rin * CLHEP::cm - thick * CLHEP::cm);
1505 rot.rotateZ(0.5 * phi * CLHEP::deg);
1506 arm.rotateZ(0.5 * phi * CLHEP::deg);
1508 for (
int i = 0; i < number; ++i) {
1509 const string physicalName =
"physicalRib5_" + to_string(rib5ID) +
" " + to_string(i);
1510 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
1512 rot.rotateZ(phi * CLHEP::deg);
1513 arm.rotateZ(phi * CLHEP::deg);