96 const G4double realTemperture = (273.15 + 23.) * CLHEP::kelvin;
106 G4double h2odensity = 1.000 * CLHEP::g / CLHEP::cm3;
107 G4double a = 1.01 * CLHEP::g / CLHEP::mole;
108 G4Element* elH =
new G4Element(
"Hydrogen",
"H", 1., a);
109 a = 16.00 * CLHEP::g / CLHEP::mole;
110 G4Element* elO =
new G4Element(
"Oxygen",
"O", 8., a);
111 G4Material* medH2O =
new G4Material(
"Water", h2odensity, 2);
112 medH2O->AddElement(elH, 2);
113 medH2O->AddElement(elO, 1);
125 const double num_senseWire =
static_cast<double>(geo.
getNSenseWires());
126 const double num_fieldWire =
static_cast<double>(geo.
getNFieldWires());
127 double totalCS = M_PI * (rmin_outerWall * rmin_outerWall - rmax_innerWall * rmax_innerWall);
130 double senseCS = M_PI * (diameter_senseWire / 2) * (diameter_senseWire / 2) * num_senseWire;
133 double fieldCS = M_PI * (diameter_fieldWire / 2) * (diameter_fieldWire / 2) * num_fieldWire;
136 const double denHelium = medHelium->GetDensity() / 2.0;
137 const double denEthane = medEthane->GetDensity() / 2.0;
138 const double denAluminum = medAluminum->GetDensity() * (fieldCS / totalCS);
139 const double denTungsten = medTungsten->GetDensity() * (senseCS / totalCS);
140 const double density = denHelium + denEthane + denAluminum + denTungsten;
141 G4Material* cdcMed =
new G4Material(
"CDCGasWire", density, 4, kStateGas, realTemperture);
142 cdcMed->AddMaterial(medHelium, denHelium / density);
143 cdcMed->AddMaterial(medEthane, denEthane / density);
144 cdcMed->AddMaterial(medTungsten, denTungsten / density);
145 cdcMed->AddMaterial(medAluminum, denAluminum / density);
147 G4Material* cdcMedGas = cdcMed;
155 const double density2 = denHelium + denEthane;
156 cdcMedGas =
new G4Material(
"CDCRealGas", density2, 2, kStateGas, realTemperture);
157 cdcMedGas->AddMaterial(medHelium, denHelium / density2);
158 cdcMedGas->AddMaterial(medEthane, denEthane / density2);
162 G4cout << *(G4Material::GetMaterialTable());
166 const auto& motherRmin = mother.
getRmin();
167 const auto& motherRmax = mother.getRmax();
168 const auto& motherZ = mother.getZ();
169 G4Polycone* solid_cdc =
170 new G4Polycone(
"solidCDC", 0 * CLHEP::deg, 360.* CLHEP::deg,
171 mother.getNNodes(), motherZ.data(),
172 motherRmin.data(), motherRmax.data());
173 m_logicalCDC =
new G4LogicalVolume(solid_cdc, medAir,
"logicalCDC", 0, 0, 0);
177 "physicalCDC", &topVolume,
false, 0);
180 G4Region* aRegion =
new G4Region(
"CDCEnvelope");
184 m_VisAttributes.push_back(
new G4VisAttributes(
true, G4Colour(0., 1., 0.)));
186 const int iOuterWall = wall.getId();
187 const string wallName = wall.getName();
188 const double wallRmin = wall.getRmin();
189 const double wallRmax = wall.getRmax();
190 const double wallZfwd = wall.getZfwd();
191 const double wallZbwd = wall.getZbwd();
192 const double length = (wallZfwd - wallZbwd) / 2.0;
196 if (strstr((wallName).c_str(),
"MiddleWall") !=
nullptr) {
199 medWall = medAluminum;
201 G4Tubs* outerWallTubeShape =
new G4Tubs(
"solid" + wallName, wallRmin * CLHEP::cm,
202 wallRmax * CLHEP::cm, length * CLHEP::cm, 0 * CLHEP::deg, 360.*CLHEP::deg);
204 G4LogicalVolume* outerWallTube =
new G4LogicalVolume(outerWallTubeShape, medWall,
"solid" + wallName, 0, 0, 0);
206 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (length + wallZbwd)*CLHEP::cm), outerWallTube,
"logical" + wallName,
211 m_VisAttributes.push_back(
new G4VisAttributes(
true, G4Colour(0., 1., 0.)));
213 const string wallName = wall.getName();
214 const double wallRmin = wall.getRmin();
215 const double wallRmax = wall.getRmax();
216 const double wallZfwd = wall.getZfwd();
217 const double wallZbwd = wall.getZbwd();
218 const double length = (wallZfwd - wallZbwd) / 2.0;
219 const int iInnerWall = wall.getId();
222 if (strstr(wallName.c_str(),
"MiddleWall") !=
nullptr) {
224 }
else if (strstr(wallName.c_str(),
"MiddleGlue") !=
nullptr) {
227 medWall = medAluminum;
230 G4Tubs* innerWallTubeShape =
new G4Tubs(
"solid" + wallName, wallRmin * CLHEP::cm,
231 wallRmax * CLHEP::cm, length * CLHEP::cm, 0 * CLHEP::deg, 360.*CLHEP::deg);
232 G4LogicalVolume* innerWallTube =
new G4LogicalVolume(innerWallTubeShape, medWall,
"logical" + wallName, 0, 0, 0);
234 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (length + wallZbwd)*CLHEP::cm), innerWallTube,
"physical" + wallName,
247 for (
int iSLayer = 0; iSLayer < nSLayer; ++iSLayer) {
251 double rmin_sensitive_left, rmax_sensitive_left;
252 double rmin_sensitive_middle, rmax_sensitive_middle;
253 double rmin_sensitive_right, rmax_sensitive_right;
254 double zback_sensitive_left, zfor_sensitive_left;
255 double zback_sensitive_middle, zfor_sensitive_middle;
256 double zback_sensitive_right, zfor_sensitive_right;
259 const auto& epLayerBwd = endplate.getEndPlateLayer(0);
260 const auto& epLayerFwd = endplate.getEndPlateLayer(nEPLayer / 2);
264 rmin_sensitive_left = epLayerBwd.getRmax();
265 rmax_sensitive_left = fieldLayer.
getR();
266 zback_sensitive_left = senseLayer.getZbwd();
267 zfor_sensitive_left = epLayerBwd.getZfwd();
269 rmin_sensitive_middle = (geo.
getInnerWall(0)).getRmax();
270 rmax_sensitive_middle = fieldLayer.getR();
271 zback_sensitive_middle = epLayerBwd.getZfwd();
272 zfor_sensitive_middle = epLayerFwd.getZbwd();
274 rmin_sensitive_right = epLayerFwd.getRmax();
275 rmax_sensitive_right = fieldLayer.getR();
276 zback_sensitive_right = epLayerFwd.getZbwd();
277 zfor_sensitive_right = senseLayer.getZfwd();
278 }
else if (iSLayer >= 1 && iSLayer <= 14) {
279 const auto& epLayerBwd = endplate.getEndPlateLayer(1);
280 const auto& epLayerFwd = endplate.getEndPlateLayer((nEPLayer / 2) + 1);
285 rmin_sensitive_left = epLayerBwd.getRmax();
286 rmax_sensitive_left = fieldLayerOut.
getR();
287 zback_sensitive_left = senseLayer.getZbwd();
288 zfor_sensitive_left = epLayerBwd.getZfwd();
290 rmin_sensitive_middle = fieldLayerIn.getR();
291 rmax_sensitive_middle = fieldLayerOut.getR();
292 zback_sensitive_middle = epLayerBwd.getZfwd();
293 zfor_sensitive_middle = epLayerFwd.getZbwd();
295 rmin_sensitive_right = epLayerFwd.getRmax();
296 rmax_sensitive_right = fieldLayerOut.getR();
297 zback_sensitive_right = epLayerFwd.getZbwd();
298 zfor_sensitive_right = senseLayer.getZfwd();
299 }
else if (iSLayer >= 15 && iSLayer <= 18) {
300 const auto& epLayerBwd = endplate.getEndPlateLayer(1);
301 const auto& epLayerFwd = endplate.getEndPlateLayer(nEPLayer / 2);
306 rmin_sensitive_left = epLayerBwd.getRmax();
307 rmax_sensitive_left = fieldLayerOut.
getR();
308 zback_sensitive_left = senseLayer.getZbwd();
309 zfor_sensitive_left = epLayerBwd.getZfwd();
311 rmin_sensitive_middle = fieldLayerIn.getR();
312 rmax_sensitive_middle = fieldLayerOut.getR();
313 zback_sensitive_middle = epLayerBwd.getZfwd();
314 zfor_sensitive_middle = epLayerFwd.getZbwd();
316 rmin_sensitive_right = epLayerFwd.getRmax();
317 rmax_sensitive_right = fieldLayerOut.getR();
318 zback_sensitive_right = epLayerFwd.getZbwd();
319 zfor_sensitive_right = senseLayer.getZfwd();
320 }
else if (iSLayer >= 19 && iSLayer < 55) {
321 const auto& epLayerBwd = endplate.getEndPlateLayer(0);
322 const auto& epLayerFwd = endplate.getEndPlateLayer(nEPLayer / 2);
327 rmin_sensitive_left = epLayerBwd.getRmax();
328 rmax_sensitive_left = fieldLayerOut.
getR();
329 zback_sensitive_left = senseLayer.getZbwd();
330 zfor_sensitive_left = epLayerBwd.getZfwd();
332 rmin_sensitive_middle = fieldLayerIn.getR();
333 rmax_sensitive_middle = fieldLayerOut.getR();
334 zback_sensitive_middle = epLayerBwd.getZfwd();
335 zfor_sensitive_middle = epLayerFwd.getZbwd();
337 rmin_sensitive_right = epLayerFwd.getRmax();
338 rmax_sensitive_right = fieldLayerOut.getR();
339 zback_sensitive_right = epLayerFwd.getZbwd();
340 zfor_sensitive_right = senseLayer.getZfwd();
342 }
else if (iSLayer == 55) {
344 const auto& epLayerBwdIn = endplate.getEndPlateLayer(0);
345 const auto& epLayerBwdOut = endplate.getEndPlateLayer((nEPLayer / 2) - 1);
346 const auto& epLayerFwdIn = endplate.getEndPlateLayer(nEPLayer / 2);
347 const auto& epLayerFwdOut = endplate.getEndPlateLayer(nEPLayer - 1);
350 int iSLayerMinus1 = iSLayer - 1;
352 rmin_sensitive_left = epLayerBwdIn.getRmax();
353 rmax_sensitive_left = epLayerBwdOut.getRmax();
354 zback_sensitive_left = senseLayer.
getZbwd();
355 zfor_sensitive_left = epLayerBwdIn.getZfwd();
357 rmin_sensitive_middle = fieldLayerIn.getR();
358 rmax_sensitive_middle = (geo.
getOuterWall(0)).getRmin();
359 zback_sensitive_middle = epLayerBwdIn.getZfwd();
360 zfor_sensitive_middle = epLayerFwdIn.getZbwd();
362 rmin_sensitive_right = epLayerFwdIn.getRmax();
363 rmax_sensitive_right = epLayerFwdOut.getRmax();
364 zback_sensitive_right = epLayerFwdIn.getZbwd();
365 zfor_sensitive_right = senseLayer.getZfwd();
368 B2ERROR(
"Undefined sensitive layer : " << iSLayer);
374 if ((zfor_sensitive_left - zback_sensitive_left) > length_feedthrough) {
391 G4Tubs* leftTubeShape =
new G4Tubs((boost::format(
"solidCDCLayer_%1%_leftTube") % iSLayer).str().c_str(),
392 rmin_sensitive_left * CLHEP::cm,
393 rmax_sensitive_left * CLHEP::cm, length_feedthrough * CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
394 G4LogicalVolume* leftTube =
new G4LogicalVolume(leftTubeShape, cdcMed,
395 (boost::format(
"logicalCDCLayer_%1%_leftTube") % iSLayer).str().c_str(), 0, 0, 0);
396 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zback_sensitive_left + length_feedthrough / 2.0)*CLHEP::cm), leftTube,
397 (boost::format(
"physicalCDCLayer_%1%_leftTube") % iSLayer).str().c_str(),
m_logicalCDC,
false, iSLayer);
399 G4Tubs* leftSensitiveTubeShape =
new G4Tubs((boost::format(
"solidSD_CDCLayer_%1%_left") % iSLayer).str().c_str(),
400 rmin_sensitive_left * CLHEP::cm, rmax_sensitive_left * CLHEP::cm,
401 (zfor_sensitive_left - zback_sensitive_left - length_feedthrough)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
402 G4LogicalVolume* leftSensitiveTube =
new G4LogicalVolume(leftSensitiveTubeShape, cdcMed,
403 (boost::format(
"logicalSD_CDCLayer_%1%_left") % iSLayer).str().c_str(), 0, 0, 0);
404 leftSensitiveTube->SetSensitiveDetector(
m_sensitive);
405 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfor_sensitive_left + zback_sensitive_left + length_feedthrough)*CLHEP::cm / 2.0),
406 leftSensitiveTube, (boost::format(
"physicalSD_CDCLayer_%1%_left") % iSLayer).str().c_str(),
m_logicalCDC,
false, iSLayer);
424 G4Tubs* leftTubeShape =
new G4Tubs((boost::format(
"solidCDCLayer_%1%_leftTube") % iSLayer).str().c_str(),
425 rmin_sensitive_left * CLHEP::cm,
426 rmax_sensitive_left * CLHEP::cm, (zfor_sensitive_left - zback_sensitive_left)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
427 G4LogicalVolume* leftTube =
new G4LogicalVolume(leftTubeShape, cdcMed,
428 (boost::format(
"logicalCDCLayer_%1%_leftTube") % iSLayer).str().c_str(), 0, 0, 0);
429 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfor_sensitive_left + zback_sensitive_left)*CLHEP::cm / 2.0), leftTube,
430 (boost::format(
"physicalCDCLayer_%1%_leftTube") % iSLayer).str().c_str(),
m_logicalCDC,
false, iSLayer);
434 G4Tubs* leftMidTubeShape =
new G4Tubs((boost::format(
"solidCDCLayer_%1%_leftMidTube") % iSLayer).str().c_str(),
435 rmin_sensitive_middle * CLHEP::cm, rmax_sensitive_middle * CLHEP::cm,
436 (length_feedthrough - zfor_sensitive_left + zback_sensitive_left)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
437 G4LogicalVolume* leftMidTube =
new G4LogicalVolume(leftMidTubeShape, cdcMed,
438 (boost::format(
"logicalCDCLayer_%1%_leftMidTube") % iSLayer).str().c_str(), 0, 0, 0);
440 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (length_feedthrough + zfor_sensitive_left + zback_sensitive_left)*CLHEP::cm / 2.0),
441 leftMidTube, (boost::format(
"physicalCDCLayer_%1%_leftMidTube") % iSLayer).str().c_str(),
m_logicalCDC,
false, iSLayer);
444 zback_sensitive_middle = length_feedthrough + zback_sensitive_left;
448 if ((zfor_sensitive_right - zback_sensitive_right) > length_feedthrough) {
465 G4Tubs* rightTubeShape =
new G4Tubs((boost::format(
"solidCDCLayer_%1%_rightTube") % iSLayer).str().c_str(),
466 rmin_sensitive_right * CLHEP::cm, rmax_sensitive_right * CLHEP::cm, length_feedthrough * CLHEP::cm / 2.0, 0 * CLHEP::deg,
468 G4LogicalVolume* rightTube =
new G4LogicalVolume(rightTubeShape, cdcMed,
469 (boost::format(
"logicalCDCLayer_%1%_rightTube") % iSLayer).str().c_str(), 0, 0, 0);
471 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfor_sensitive_right - length_feedthrough / 2.0)*CLHEP::cm), rightTube,
472 (boost::format(
"physicalCDCLayer_%1%_rightTube") % iSLayer).str().c_str(),
m_logicalCDC,
false, iSLayer);
476 G4Tubs* rightSensitiveTubeShape =
new G4Tubs((boost::format(
"solidSD_CDCLayer_%1%_right") % iSLayer).str().c_str(),
477 rmin_sensitive_right * CLHEP::cm, rmax_sensitive_right * CLHEP::cm,
478 (zfor_sensitive_right - zback_sensitive_right - length_feedthrough)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
479 G4LogicalVolume* rightSensitiveTube =
new G4LogicalVolume(rightSensitiveTubeShape, cdcMed,
480 (boost::format(
"logicalSD_CDCLayer_%1%_right") % iSLayer).str().c_str(), 0, 0, 0);
481 rightSensitiveTube->SetSensitiveDetector(
m_sensitive);
483 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfor_sensitive_right + zback_sensitive_right - length_feedthrough)*CLHEP::cm / 2.0),
484 rightSensitiveTube, (boost::format(
"physicalSD_CDCLayer_%1%_right") % iSLayer).str().c_str(),
m_logicalCDC,
false, iSLayer);
503 G4Tubs* rightTubeShape =
new G4Tubs((boost::format(
"solidCDCLayer_%1%_rightTube") % iSLayer).str().c_str(),
504 rmin_sensitive_right * CLHEP::cm, rmax_sensitive_right * CLHEP::cm, (zfor_sensitive_right - zback_sensitive_right)*CLHEP::cm / 2.0,
505 0 * CLHEP::deg, 360.*CLHEP::deg);
506 G4LogicalVolume* rightTube =
new G4LogicalVolume(rightTubeShape, cdcMed,
507 (boost::format(
"logicalCDCLayer_%1%_rightTube") % iSLayer).str().c_str(), 0, 0, 0);
509 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfor_sensitive_right + zback_sensitive_right)*CLHEP::cm / 2.0), rightTube,
510 (boost::format(
"physicalCDCLayer_%1%_rightTube") % iSLayer).str().c_str(),
m_logicalCDC,
false, iSLayer);
514 G4Tubs* rightMidTubeShape =
new G4Tubs((boost::format(
"solidCDCLayer_%1%_rightMidTube") % iSLayer).str().c_str(),
515 rmin_sensitive_middle * CLHEP::cm, rmax_sensitive_middle * CLHEP::cm,
516 (length_feedthrough - zfor_sensitive_right + zback_sensitive_right)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
517 G4LogicalVolume* rightMidTube =
new G4LogicalVolume(rightMidTubeShape, cdcMed,
518 (boost::format(
"logicalCDCLayer_%1%_rightMidTube") % iSLayer).str().c_str(), 0, 0, 0);
519 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zback_sensitive_right - length_feedthrough + zfor_sensitive_right)*CLHEP::cm / 2.0),
520 rightMidTube, (boost::format(
"physicalCDCLayer_%1%_rightMidTube") % iSLayer).str().c_str(),
m_logicalCDC,
false, iSLayer);
523 zfor_sensitive_middle = zfor_sensitive_right - length_feedthrough;
528 G4Tubs* middleSensitiveTubeShape =
new G4Tubs((boost::format(
"solidSD_CDCLayer_%1%_middle") % iSLayer).str().c_str(),
529 rmin_sensitive_middle * CLHEP::cm, rmax_sensitive_middle * CLHEP::cm,
530 (zfor_sensitive_middle - zback_sensitive_middle)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
531 G4LogicalVolume* middleSensitiveTube =
new G4LogicalVolume(middleSensitiveTubeShape, cdcMedGas,
532 (boost::format(
"logicalSD_CDCLayer_%1%_middle") % iSLayer).str().c_str(), 0, 0, 0);
535 G4UserLimits* uLimits =
new G4UserLimits(8.5 * CLHEP::cm);
537 middleSensitiveTube->SetUserLimits(uLimits);
538 middleSensitiveTube->SetSensitiveDetector(
m_sensitive);
540 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfor_sensitive_middle + zback_sensitive_middle)*CLHEP::cm / 2.0), middleSensitiveTube,
541 (boost::format(
"physicalSD_CDCLayer_%1%_middle") % iSLayer).str().c_str(),
m_logicalCDC,
false, iSLayer);
545 G4String sName =
"sWire";
550 G4double tAtZ0 = -wb0.
Z() / (wf0.
Z() - wb0.
Z());
553 const G4double epsl = 25.e-4;
554 G4double reductionBwd = (zback_sensitive_middle + epsl) / wb0.
Z();
556 wb0 = reductionBwd * (wb0 - wAtZ0) + wAtZ0;
558 G4double reductionFwd = (zfor_sensitive_middle - epsl) / wf0.
Z();
559 wf0 = reductionFwd * (wf0 - wAtZ0) + wAtZ0;
561 const G4double wireHalfLength = 0.5 * (wf0 - wb0).Mag() * CLHEP::cm;
564 G4Tubs* middleSensitiveSwireShape =
new G4Tubs(sName, 0., sWireRadius, wireHalfLength, 0., 360. * CLHEP::deg);
565 G4LogicalVolume* middleSensitiveSwire =
new G4LogicalVolume(middleSensitiveSwireShape, medTungsten, sName);
569 G4String fName =
"fWire";
571 G4Tubs* middleSensitiveFwireShape =
new G4Tubs(fName, 0., fWireRadius, wireHalfLength, 0., 360. * CLHEP::deg);
572 G4LogicalVolume* middleSensitiveFwire =
new G4LogicalVolume(middleSensitiveFwireShape, medAluminum, fName);
579 const G4double dphi = M_PI / nCells;
582 for (
int ic = 0; ic < nCells; ++ic) {
586 G4double tAtZ02 = -wb.
Z() / (wf.
Z() - wb.
Z());
588 G4double reductionBwd2 = (zback_sensitive_middle + epsl) / wb.
Z();
589 wb = reductionBwd2 * (wb - wAtZ02) + wAtZ02;
590 G4double reductionFwd2 = (zfor_sensitive_middle - epsl) / wf.
Z();
591 wf = reductionFwd2 * (wf - wAtZ02) + wAtZ02;
593 G4double thetaYZ = -asin((wf - wb).Y() / (wf - wb).Mag());
595 B2Vector3D fMinusBInZX((wf - wb).X(), 0., (wf - wb).Z());
596 G4double thetaZX = asin((unitZ.
Cross(fMinusBInZX)).Y() / fMinusBInZX.
Mag());
597 G4RotationMatrix rotM;
599 rotM.rotateX(thetaYZ * CLHEP::rad);
600 rotM.rotateY(thetaZX * CLHEP::rad);
602 G4ThreeVector xyz(0.5 * (wb.
X() + wf.
X()) * CLHEP::cm,
603 0.5 * (wb.
Y() + wf.
Y()) * CLHEP::cm, 0.);
607 new G4PVPlacement(G4Transform3D(rotM, xyz), middleSensitiveSwire, sName, middleSensitiveTube,
false, ic);
611 G4double rF = rmax_sensitive_middle - 0.5 * diameter;
613 G4double phi = atan2(wbF.
Y(), wbF.
X());
614 wbF.
SetX(rF * cos(phi));
615 wbF.
SetY(rF * sin(phi));
618 rF = rmax_sensitive_middle - 0.5 * diameter;
619 phi = atan2(wfF.
Y(), wfF.
X());
620 wfF.
SetX(rF * cos(phi));
621 wfF.
SetY(rF * sin(phi));
623 thetaYZ = -asin((wfF - wbF).Y() / (wfF - wbF).Mag());
625 fMinusBInZX = wfF - wbF;
626 fMinusBInZX.
SetY(0.);
627 thetaZX = asin((unitZ.
Cross(fMinusBInZX)).Y() / fMinusBInZX.
Mag());
629 G4RotationMatrix rotM1;
630 rotM1.rotateX(thetaYZ * CLHEP::rad);
631 rotM1.rotateY(thetaZX * CLHEP::rad);
633 xyz.setX(0.5 * (wbF.
X() + wfF.
X()) * CLHEP::cm);
634 xyz.setY(0.5 * (wbF.
Y() + wfF.
Y()) * CLHEP::cm);
636 if (iSLayer != nSLayer - 1) {
638 new G4PVPlacement(G4Transform3D(rotM1, xyz), middleSensitiveFwire, fName, middleSensitiveTube,
false, ic);
644 phi = atan2(wbF.
Y(), wbF.
X());
645 wbF.
SetX(rF * cos(phi + dphi));
646 wbF.
SetY(rF * sin(phi + dphi));
650 phi = atan2(wfF.
Y(), wfF.
X());
651 wfF.
SetX(rF * cos(phi + dphi));
652 wfF.
SetY(rF * sin(phi + dphi));
654 thetaYZ = -asin((wfF - wbF).Y() / (wfF - wbF).Mag());
656 fMinusBInZX = wfF - wbF;
657 fMinusBInZX.
SetY(0.);
658 thetaZX = asin((unitZ.
Cross(fMinusBInZX)).Y() / fMinusBInZX.
Mag());
660 G4RotationMatrix rotM2;
661 rotM2.rotateX(thetaYZ * CLHEP::rad);
662 rotM2.rotateY(thetaZX * CLHEP::rad);
664 xyz.setX(0.5 * (wbF.
X() + wfF.
X()) * CLHEP::cm);
665 xyz.setY(0.5 * (wbF.
Y() + wfF.
Y()) * CLHEP::cm);
668 new G4PVPlacement(G4Transform3D(rotM2, xyz), middleSensitiveFwire, fName, middleSensitiveTube,
false, ic + nCells);
672 rF = rmax_sensitive_middle - 0.5 * diameter;
673 phi = atan2(wbF.
Y(), wbF.
X());
674 wbF.
SetX(rF * cos(phi + dphi));
675 wbF.
SetY(rF * sin(phi + dphi));
678 rF = rmax_sensitive_middle - 0.5 * diameter;
679 phi = atan2(wfF.
Y(), wfF.
X());
680 wfF.
SetX(rF * cos(phi + dphi));
681 wfF.
SetY(rF * sin(phi + dphi));
683 thetaYZ = -asin((wfF - wbF).Y() / (wfF - wbF).Mag());
685 fMinusBInZX = wfF - wbF;
686 fMinusBInZX.
SetY(0.);
687 thetaZX = asin((unitZ.
Cross(fMinusBInZX)).Y() / fMinusBInZX.
Mag());
689 G4RotationMatrix rotM3;
690 rotM3.rotateX(thetaYZ * CLHEP::rad);
691 rotM3.rotateY(thetaZX * CLHEP::rad);
693 xyz.setX(0.5 * (wbF.
X() + wfF.
X()) * CLHEP::cm);
694 xyz.setY(0.5 * (wbF.
Y() + wfF.
Y()) * CLHEP::cm);
696 if (iSLayer != nSLayer - 1) {
697 new G4PVPlacement(G4Transform3D(rotM3, xyz), middleSensitiveFwire, fName, middleSensitiveTube,
false, ic + 2 * nCells);
707 m_VisAttributes.push_back(
new G4VisAttributes(
true, G4Colour(1., 1., 0.)));
709 for (
const auto& epLayer : endplate.getEndPlateLayers()) {
710 const int iEPLayer = epLayer.getILayer();
711 const string name = epLayer.getName();
712 const double rmin = epLayer.getRmin();
713 const double rmax = epLayer.getRmax();
714 const double zbwd = epLayer.getZbwd();
715 const double zfwd = epLayer.getZfwd();
716 const double length = (zfwd - zbwd) / 2.0;
718 G4Tubs* tube =
new G4Tubs(
"solidCDCEndplate" + name, rmin * CLHEP::cm,
719 rmax * CLHEP::cm, length * CLHEP::cm, 0 * CLHEP::deg, 360.*CLHEP::deg);
720 G4LogicalVolume* logical =
new G4LogicalVolume(tube,
Materials::get(
"G4_Al"),
721 "logicalCDCEndplate" + name, 0, 0);
723 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfwd + zbwd)*CLHEP::cm / 2.0), logical,
724 "physicalCDCEndplate" + name,
m_logicalCDC,
false, iEPLayer);
733 const int iEB = frontend.getId();
734 const double ebInnerR = frontend.getRmin();
735 const double ebOuterR = frontend.getRmax();
736 const double ebBZ = frontend.getZbwd();
737 const double ebFZ = frontend.getZfwd();
739 G4Tubs* ebTubeShape =
new G4Tubs((boost::format(
"solidSD_ElectronicsBoard_Layer%1%") % iEB).str().c_str(), ebInnerR * CLHEP::cm,
740 ebOuterR * CLHEP::cm, (ebFZ - ebBZ)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
742 G4LogicalVolume* ebTube =
new G4LogicalVolume(ebTubeShape, medNEMA_G10_Plate,
743 (boost::format(
"logicalSD_ElectronicsBoard_Layer%1%") % iEB).str().c_str(), 0, 0, 0);
747 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (ebFZ + ebBZ)*CLHEP::cm / 2.0), ebTube,
748 (boost::format(
"physicalSD_ElectronicsBoard_Layer%1%") % iEB).str().c_str(),
m_logicalCDC,
false, iEB);
769 for (
const auto& rib : geo.
getRibs()) {
771 const int id = rib.getId();
772 const double length = rib.getLength();
773 const double width = rib.getWidth();
774 const double thick = rib.getThick();
775 const double rotx = rib.getRotX();
776 const double roty = rib.getRotY();
777 const double rotz = rib.getRotZ();
778 const double x = rib.getX();
779 const double y = rib.getY();
780 const double z = rib.getZ();
781 const int offset = rib.getOffset();
782 const int ndiv = rib.getNDiv();
784 const string solidName =
"solidRib" + to_string(
id);
785 const string logicalName =
"logicalRib" + to_string(
id);
786 G4Box* boxShape =
new G4Box(solidName, 0.5 * length * CLHEP::cm,
787 0.5 * width * CLHEP::cm,
788 0.5 * thick * CLHEP::cm);
790 const double rmax = 0.5 * length;
791 const double rmin = max((rmax - thick), 0.);
792 G4Tubs* tubeShape =
new G4Tubs(solidName,
795 0.5 * width * CLHEP::cm,
802 G4LogicalVolume* logicalV =
new G4LogicalVolume(boxShape, medAluminum, logicalName, 0, 0, 0);
803 if (
id > 39 &&
id < 78)
804 logicalV =
new G4LogicalVolume(boxShape, medCopper, logicalName, 0, 0, 0);
805 if ((
id > 77 &&
id < 94) || (
id > 131 &&
id < 146))
806 logicalV =
new G4LogicalVolume(boxShape, medNEMA_G10_Plate, logicalName, 0, 0, 0);
807 if (
id > 93 &&
id < 110)
808 logicalV =
new G4LogicalVolume(tubeShape, medCopper, logicalName, 0, 0, 0);
809 if (
id > 109 &&
id < 126)
810 logicalV =
new G4LogicalVolume(tubeShape, medH2O, logicalName, 0, 0, 0);
811 if (
id > 127 &&
id < 132)
812 logicalV =
new G4LogicalVolume(boxShape, medHV, logicalName, 0, 0, 0);
822 const double phi = 360.0 / ndiv;
824 G4RotationMatrix rot = G4RotationMatrix();
826 if (
id > 93 &&
id < 126) dz = 0;
828 G4ThreeVector arm(x * CLHEP::cm, y * CLHEP::cm, z * CLHEP::cm - dz * CLHEP::cm / 2.0);
833 rot.rotateZ(0.5 * phi * CLHEP::deg);
834 arm.rotateZ(0.5 * phi * CLHEP::deg);
836 for (
int i = 0; i < ndiv; ++i) {
837 const string physicalName =
"physicalRib_" + to_string(
id) +
" " + to_string(i);
838 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
840 rot.rotateZ(phi * CLHEP::deg);
841 arm.rotateZ(phi * CLHEP::deg);
849 for (
const auto& rib2 : geo.
getRib2s()) {
851 const int id = rib2.getId();
852 const double length = rib2.getLength();
853 const double width = rib2.getWidth();
854 const double thick = rib2.getThick();
855 const double width2 = rib2.getWidth2();
856 const double thick2 = rib2.getThick2();
857 const double rotx = rib2.getRotX();
858 const double roty = rib2.getRotY();
859 const double rotz = rib2.getRotZ();
860 const double x = rib2.getX();
861 const double y = rib2.getY();
862 const double z = rib2.getZ();
863 const int ndiv = rib2.getNDiv();
865 const string solidName =
"solidRib2" + to_string(
id);
866 const string logicalName =
"logicalRib2" + to_string(
id);
867 G4Trd* trdShape =
new G4Trd(solidName,
868 0.5 * thick * CLHEP::cm,
869 0.5 * thick2 * CLHEP::cm,
870 0.5 * width * CLHEP::cm,
871 0.5 * width2 * CLHEP::cm,
872 0.5 * length * CLHEP::cm);
874 G4LogicalVolume* logicalV =
new G4LogicalVolume(trdShape, medAluminum, logicalName, 0, 0, 0);
877 logicalV =
new G4LogicalVolume(trdShape, medCopper, logicalName, 0, 0, 0);
881 const double phi = 360.0 / ndiv;
883 G4RotationMatrix rot = G4RotationMatrix();
884 G4ThreeVector arm(x * CLHEP::cm, y * CLHEP::cm, z * CLHEP::cm - thick * CLHEP::cm / 2.0);
889 for (
int i = 0; i < ndiv; ++i) {
890 const string physicalName =
"physicalRib2_" + to_string(
id) +
" " + to_string(i);
891 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
893 rot.rotateZ(phi * CLHEP::deg);
894 arm.rotateZ(phi * CLHEP::deg);
902 for (
const auto& rib3 : geo.
getRib3s()) {
904 const int id = rib3.getId();
905 const double length = rib3.getLength();
906 const double width = rib3.getWidth();
907 const double thick = rib3.getThick();
908 const double r = rib3.getR();
909 const double x = rib3.getX();
910 const double y = rib3.getY();
911 const double z = rib3.getZ();
912 const double rx = rib3.getRx();
913 const double ry = rib3.getRy();
914 const double rz = rib3.getRz();
915 const int offset = rib3.getOffset();
916 const int ndiv = rib3.getNDiv();
918 const string logicalName =
"logicalRib3" + to_string(
id);
919 G4VSolid* boxShape =
new G4Box(
"Block",
920 0.5 * length * CLHEP::cm,
921 0.5 * width * CLHEP::cm,
922 0.5 * thick * CLHEP::cm);
923 G4VSolid* tubeShape =
new G4Tubs(
"Hole",
930 G4RotationMatrix rotsub = G4RotationMatrix();
931 rotsub.rotateX(90. * CLHEP::deg);
932 G4ThreeVector trnsub(rx * CLHEP::cm - x * CLHEP::cm, ry * CLHEP::cm - y * CLHEP::cm,
933 rz * CLHEP::cm - z * CLHEP::cm + 0.5 * thick * CLHEP::cm);
934 G4VSolid* coolingBlock =
new G4SubtractionSolid(
"Block-Hole",
937 G4Transform3D(rotsub,
940 G4LogicalVolume* logicalV =
new G4LogicalVolume(coolingBlock, medCopper, logicalName, 0, 0, 0);
944 const double phi = 360.0 / ndiv;
946 G4RotationMatrix rot = G4RotationMatrix();
947 G4ThreeVector arm(x * CLHEP::cm, y * CLHEP::cm, z * CLHEP::cm - thick * CLHEP::cm / 2.0);
950 rot.rotateZ(0.5 * phi * CLHEP::deg);
951 arm.rotateZ(0.5 * phi * CLHEP::deg);
953 for (
int i = 0; i < ndiv; ++i) {
954 const string physicalName =
"physicalRib3_" + to_string(
id) +
" " + to_string(i);
955 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
957 rot.rotateZ(phi * CLHEP::deg);
958 arm.rotateZ(phi * CLHEP::deg);
966 for (
const auto& rib4 : geo.
getRib4s()) {
968 const int id = rib4.getId();
969 const double length = rib4.getLength();
970 const double width = rib4.getWidth();
971 const double thick = rib4.getThick();
972 const double length2 = rib4.getLength2();
973 const double width2 = rib4.getWidth2();
974 const double thick2 = rib4.getThick2();
975 const double x = rib4.getX();
976 const double y = rib4.getY();
977 const double z = rib4.getZ();
978 const double x2 = rib4.getX2();
979 const double y2 = rib4.getY2();
980 const double z2 = rib4.getZ2();
981 const int offset = rib4.getOffset();
982 const int ndiv = rib4.getNDiv();
984 const string logicalName =
"logicalRib4" + to_string(
id);
985 G4VSolid* baseShape =
new G4Box(
"Base",
986 0.5 * length * CLHEP::cm,
987 0.5 * width * CLHEP::cm,
988 0.5 * thick * CLHEP::cm);
989 G4VSolid* sqShape =
new G4Box(
"Sq",
990 0.5 * length2 * CLHEP::cm,
991 0.5 * width2 * CLHEP::cm,
992 0.5 * thick2 * CLHEP::cm);
994 G4RotationMatrix rotsub = G4RotationMatrix();
995 double dzc = (z2 - thick2 / 2.) - (z - thick / 2.);
996 G4ThreeVector trnsub(x2 * CLHEP::cm - x * CLHEP::cm,
997 y2 * CLHEP::cm - y * CLHEP::cm,
999 G4VSolid* sqHoleBase =
new G4SubtractionSolid(
"Box-Sq",
1002 G4Transform3D(rotsub,
1006 G4LogicalVolume* logicalV =
new G4LogicalVolume(sqHoleBase, medCopper, logicalName, 0, 0, 0);
1008 logicalV =
new G4LogicalVolume(sqHoleBase, medNEMA_G10_Plate, logicalName, 0, 0, 0);
1011 logicalV->SetSensitiveDetector(sensitiveDetector);
1017 const double phi = 360.0 / ndiv;
1019 G4RotationMatrix rot = G4RotationMatrix();
1020 G4ThreeVector arm(x * CLHEP::cm, y * CLHEP::cm, z * CLHEP::cm - thick * CLHEP::cm / 2.0);
1023 rot.rotateZ(0.5 * phi * CLHEP::deg);
1024 arm.rotateZ(0.5 * phi * CLHEP::deg);
1026 for (
int i = 0; i < ndiv; ++i) {
1027 const string physicalName =
"physicalRib4_" + to_string(
id) +
" " + to_string(i);
1028 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
1030 rot.rotateZ(phi * CLHEP::deg);
1031 arm.rotateZ(phi * CLHEP::deg);
1038 for (
const auto& rib5 : geo.
getRib5s()) {
1040 const int id = rib5.getId();
1041 const double dr = rib5.getDr();
1042 const double dz = rib5.getDz();
1043 const double width = rib5.getWidth();
1044 const double thick = rib5.getThick();
1045 const double rin = rib5.getRin();
1046 const double x = rib5.getX();
1047 const double y = rib5.getY();
1048 const double z = rib5.getZ();
1049 const double rotx = rib5.getRotx();
1050 const double roty = rib5.getRoty();
1051 const double rotz = rib5.getRotz();
1052 const int offset = rib5.getOffset();
1053 const int ndiv = rib5.getNDiv();
1055 const string solidName =
"solidRib5" + to_string(
id);
1056 const string logicalName =
"logicalRib5" + to_string(
id);
1058 const double rmax = rin + thick;
1059 const double rmin = rin;
1060 const double dphi = 2. * atan2(dz, dr);
1061 const double ddphi = thick *
tan(dphi) / rin;
1062 const double ddphi2 = width / 2. * width / 2. / (x + dr) / rin;
1063 const double cphi = dphi - ddphi - ddphi2;
1064 G4Tubs* tubeShape =
new G4Tubs(solidName,
1067 0.5 * width * CLHEP::cm,
1071 G4LogicalVolume* logicalV =
new G4LogicalVolume(tubeShape, medAluminum, logicalName, 0, 0, 0);
1075 const double phi = 360.0 / ndiv;
1077 G4RotationMatrix rot = G4RotationMatrix();
1080 G4ThreeVector arm(x * CLHEP::cm, y * CLHEP::cm, z * CLHEP::cm - rin * CLHEP::cm - thick * CLHEP::cm);
1085 rot.rotateZ(0.5 * phi * CLHEP::deg);
1086 arm.rotateZ(0.5 * phi * CLHEP::deg);
1088 for (
int i = 0; i < ndiv; ++i) {
1089 const string physicalName =
"physicalRib5_" + to_string(
id) +
" " + to_string(i);
1090 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
1092 rot.rotateZ(phi * CLHEP::deg);
1093 arm.rotateZ(phi * CLHEP::deg);
1187 string Aluminum = content.getString(
"Aluminum");
1190 G4double density = 1.000 * CLHEP::g / CLHEP::cm3;
1191 G4double a = 1.01 * CLHEP::g / CLHEP::mole;
1192 G4Element* elH =
new G4Element(
"Hydrogen",
"H", 1., a);
1193 a = 16.00 * CLHEP::g / CLHEP::mole;
1194 G4Element* elO =
new G4Element(
"Oxygen",
"O", 8., a);
1195 G4Material* medH2O =
new G4Material(
"Water", density, 2);
1196 medH2O->AddElement(elH, 2);
1197 medH2O->AddElement(elO, 1);
1205 m_VisAttributes.push_back(
new G4VisAttributes(
true, G4Colour(0., 1., 0.)));
1206 const int nCover = content.getNumberNodes(
"Covers/Cover");
1207 for (
int iCover = 0; iCover < nCover; ++iCover) {
1208 GearDir coverContent(content);
1209 coverContent.
append((boost::format(
"/Covers/Cover[%1%]/") % (iCover + 1)).str());
1210 const string scoverID = coverContent.
getString(
"@id");
1211 const int coverID = atoi(scoverID.c_str());
1212 const string coverName = coverContent.
getString(
"Name");
1213 const double coverInnerR1 = coverContent.
getLength(
"InnerR1");
1214 const double coverInnerR2 = coverContent.
getLength(
"InnerR2");
1215 const double coverOuterR1 = coverContent.
getLength(
"OuterR1");
1216 const double coverOuterR2 = coverContent.
getLength(
"OuterR2");
1217 const double coverThick = coverContent.
getLength(
"Thickness");
1218 const double coverPosZ = coverContent.
getLength(
"PosZ");
1220 const double rmin1 = coverInnerR1;
1221 const double rmax1 = coverOuterR1;
1222 const double rmin2 = coverInnerR2;
1223 const double rmax2 = coverOuterR2;
1234 if (coverID == 7 || coverID == 10) {
1235 createCone(rmin1, rmax1, rmin2, rmax2, coverThick, coverPosZ, coverID, medAluminum, coverName);
1237 createTube(rmin1, rmax1, coverThick, coverPosZ, coverID, medAluminum, coverName);
1240 if (coverID > 22 && coverID < 29)
1241 createTube(rmin1, rmax1, coverThick, coverPosZ, coverID, medCopper, coverName);
1242 if (coverID > 28 && coverID < 35)
1243 createTorus(rmin1, rmax1, coverThick, coverPosZ, coverID, medCopper, coverName);
1244 if (coverID > 34 && coverID < 41)
1245 createTorus(rmin1, rmax1, coverThick, coverPosZ, coverID, medH2O, coverName);
1246 if (coverID == 45 || coverID == 46)
1247 createTube(rmin1, rmax1, coverThick, coverPosZ, coverID, medLV, coverName);
1248 if (coverID == 47 || coverID == 48)
1249 createTube(rmin1, rmax1, coverThick, coverPosZ, coverID, medFiber, coverName);
1250 if (coverID == 49 || coverID == 50)
1251 createTube(rmin1, rmax1, coverThick, coverPosZ, coverID, medCAT7, coverName);
1252 if (coverID == 51 || coverID == 52)
1253 createTube(rmin1, rmax1, coverThick, coverPosZ, coverID, medTRG, coverName);
1255 createTube(rmin1, rmax1, coverThick, coverPosZ, coverID, medHV, coverName);
1258 const int nCover2 = content.getNumberNodes(
"Covers/Cover2");
1259 for (
int iCover2 = 0; iCover2 < nCover2; ++iCover2) {
1260 GearDir cover2Content(content);
1261 cover2Content.
append((boost::format(
"/Cover2s/Cover2[%1%]/") % (iCover2 + 1)).str());
1262 const string scover2ID = cover2Content.
getString(
"@id");
1263 const int cover2ID = atoi(scover2ID.c_str());
1264 const string cover2Name = cover2Content.
getString(
"Name");
1265 const double cover2InnerR = cover2Content.
getLength(
"InnerR");
1266 const double cover2OuterR = cover2Content.
getLength(
"OuterR");
1267 const double cover2StartPhi = cover2Content.
getLength(
"StartPhi");
1268 const double cover2DeltaPhi = cover2Content.
getLength(
"DeltaPhi");
1269 const double cover2Thick = cover2Content.
getLength(
"Thickness");
1270 const double cover2PosZ = cover2Content.
getLength(
"PosZ");
1273 createTube2(cover2InnerR, cover2OuterR, cover2StartPhi, cover2DeltaPhi, cover2Thick, cover2PosZ, cover2ID, medHV, cover2Name);
1274 if (cover2ID > 10 && cover2ID < 14)
1275 createTube2(cover2InnerR, cover2OuterR, cover2StartPhi, cover2DeltaPhi, cover2Thick, cover2PosZ, cover2ID, medFiber, cover2Name);
1276 if (cover2ID > 13 && cover2ID < 23)
1277 createTube2(cover2InnerR, cover2OuterR, cover2StartPhi, cover2DeltaPhi, cover2Thick, cover2PosZ, cover2ID, medCAT7, cover2Name);
1278 if (cover2ID > 22 && cover2ID < 29)
1279 createTube2(cover2InnerR, cover2OuterR, cover2StartPhi, cover2DeltaPhi, cover2Thick, cover2PosZ, cover2ID, medTRG, cover2Name);
1282 const int nRibs = content.getNumberNodes(
"Covers/Rib");
1283 for (
int iRib = 0; iRib < nRibs; ++iRib) {
1285 ribContent.
append((boost::format(
"/Covers/Rib[%1%]/") % (iRib + 1)).str());
1286 const string sribID = ribContent.
getString(
"@id");
1287 const int ribID = atoi(sribID.c_str());
1289 const double length = ribContent.
getLength(
"Length");
1290 const double width = ribContent.
getLength(
"Width");
1291 const double thick = ribContent.
getLength(
"Thickness");
1292 const double rotX = ribContent.
getLength(
"RotX");
1293 const double rotY = ribContent.
getLength(
"RotY");
1294 const double rotZ = ribContent.
getLength(
"RotZ");
1295 const double cX = ribContent.
getLength(
"PosX");
1296 const double cY = ribContent.
getLength(
"PosY");
1297 const double cZ = ribContent.
getLength(
"PosZ");
1298 const int offset = atoi((ribContent.
getString(
"Offset")).c_str());
1299 const int number = atoi((ribContent.
getString(
"NDiv")).c_str());
1301 const string solidName =
"solidRib" + to_string(ribID);
1302 const string logicalName =
"logicalRib" + to_string(ribID);
1303 G4Box* boxShape =
new G4Box(solidName, 0.5 * length * CLHEP::cm,
1304 0.5 * width * CLHEP::cm,
1305 0.5 * thick * CLHEP::cm);
1306 const double rmax = 0.5 * length;
1307 const double rmin = max((rmax - thick), 0.);
1308 G4Tubs* tubeShape =
new G4Tubs(solidName,
1311 0.5 * width * CLHEP::cm,
1318 G4LogicalVolume* logicalV =
new G4LogicalVolume(boxShape, medAluminum, logicalName, 0, 0, 0);
1319 if (ribID > 39 && ribID < 78)
1320 logicalV =
new G4LogicalVolume(boxShape, medCopper, logicalName, 0, 0, 0);
1321 if ((ribID > 77 && ribID < 94) || (ribID > 131 && ribID < 146))
1322 logicalV =
new G4LogicalVolume(boxShape, medNEMA_G10_Plate, logicalName, 0, 0, 0);
1323 if (ribID > 93 && ribID < 110)
1324 logicalV =
new G4LogicalVolume(tubeShape, medCopper, logicalName, 0, 0, 0);
1325 if (ribID > 109 && ribID < 126)
1326 logicalV =
new G4LogicalVolume(tubeShape, medH2O, logicalName, 0, 0, 0);
1327 if (ribID > 127 && ribID < 132)
1328 logicalV =
new G4LogicalVolume(boxShape, medHV, logicalName, 0, 0, 0);
1338 const double phi = 360.0 / number;
1340 G4RotationMatrix rot = G4RotationMatrix();
1343 if (ribID > 93 && ribID < 126) dz = 0;
1344 G4ThreeVector arm(cX * CLHEP::cm, cY * CLHEP::cm, cZ * CLHEP::cm - dz * CLHEP::cm / 2.0);
1350 rot.rotateZ(0.5 * phi * CLHEP::deg);
1351 arm.rotateZ(0.5 * phi * CLHEP::deg);
1353 for (
int i = 0; i < number; ++i) {
1354 const string physicalName =
"physicalRib_" + to_string(ribID) +
" " + to_string(i);
1355 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
1357 rot.rotateZ(phi * CLHEP::deg);
1358 arm.rotateZ(phi * CLHEP::deg);
1363 const int nRib2s = content.getNumberNodes(
"Covers/Rib2");
1364 for (
int iRib2 = 0; iRib2 < nRib2s; ++iRib2) {
1366 rib2Content.
append((boost::format(
"/Covers/Rib2[%1%]/") % (iRib2 + 1)).str());
1367 const string srib2ID = rib2Content.
getString(
"@id");
1368 const int rib2ID = atoi(srib2ID.c_str());
1370 const double length = rib2Content.
getLength(
"Length");
1371 const double width = rib2Content.
getLength(
"Width");
1372 const double thick = rib2Content.
getLength(
"Thickness");
1373 const double width2 = rib2Content.
getLength(
"Width2");
1374 const double thick2 = rib2Content.
getLength(
"Thickness2");
1375 const double rotX = rib2Content.
getLength(
"RotX");
1376 const double rotY = rib2Content.
getLength(
"RotY");
1377 const double rotZ = rib2Content.
getLength(
"RotZ");
1378 const double cX = rib2Content.
getLength(
"PosX");
1379 const double cY = rib2Content.
getLength(
"PosY");
1380 const double cZ = rib2Content.
getLength(
"PosZ");
1381 const int number = atoi((rib2Content.
getString(
"NDiv")).c_str());
1383 const string solidName =
"solidRib2" + to_string(rib2ID);
1384 const string logicalName =
"logicalRib2" + to_string(rib2ID);
1385 G4Trd* trdShape =
new G4Trd(solidName,
1386 0.5 * thick * CLHEP::cm,
1387 0.5 * thick2 * CLHEP::cm,
1388 0.5 * width * CLHEP::cm,
1389 0.5 * width2 * CLHEP::cm,
1390 0.5 * length * CLHEP::cm);
1392 G4LogicalVolume* logicalV =
new G4LogicalVolume(trdShape, medAluminum, logicalName, 0, 0, 0);
1394 logicalV =
new G4LogicalVolume(trdShape, medCopper, logicalName, 0, 0, 0);
1398 const double phi = 360.0 / number;
1400 G4RotationMatrix rot = G4RotationMatrix();
1401 G4ThreeVector arm(cX * CLHEP::cm, cY * CLHEP::cm, cZ * CLHEP::cm - thick * CLHEP::cm / 2.0);
1406 for (
int i = 0; i < number; ++i) {
1407 const string physicalName =
"physicalRib2_" + to_string(rib2ID) +
" " + to_string(i);
1408 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
1410 rot.rotateZ(phi * CLHEP::deg);
1411 arm.rotateZ(phi * CLHEP::deg);
1416 const int nRib3s = content.getNumberNodes(
"Covers/Rib3");
1417 for (
int iRib3 = 0; iRib3 < nRib3s; ++iRib3) {
1419 rib3Content.
append((boost::format(
"/Covers/Rib3[%1%]/") % (iRib3 + 1)).str());
1420 const string srib3ID = rib3Content.
getString(
"@id");
1421 const int rib3ID = atoi(srib3ID.c_str());
1423 const double length = rib3Content.
getLength(
"Length");
1424 const double width = rib3Content.
getLength(
"Width");
1425 const double thick = rib3Content.
getLength(
"Thickness");
1426 const double r = rib3Content.
getLength(
"HoleR");
1427 const double cX = rib3Content.
getLength(
"PosX");
1428 const double cY = rib3Content.
getLength(
"PosY");
1429 const double cZ = rib3Content.
getLength(
"PosZ");
1430 const double hX = rib3Content.
getLength(
"HoleX");
1431 const double hY = rib3Content.
getLength(
"HoleY");
1432 const double hZ = rib3Content.
getLength(
"HoleZ");
1433 const int offset = atoi((rib3Content.
getString(
"Offset")).c_str());
1434 const int number = atoi((rib3Content.
getString(
"NDiv")).c_str());
1436 const string logicalName =
"logicalRib3" + to_string(rib3ID);
1437 G4VSolid* boxShape =
new G4Box(
"Block",
1438 0.5 * length * CLHEP::cm,
1439 0.5 * width * CLHEP::cm,
1440 0.5 * thick * CLHEP::cm);
1441 G4VSolid* tubeShape =
new G4Tubs(
"Hole",
1447 G4RotationMatrix rotsub = G4RotationMatrix();
1448 G4ThreeVector trnsub(cX * CLHEP::cm - hX * CLHEP::cm, cY * CLHEP::cm - hY * CLHEP::cm,
1449 cZ * CLHEP::cm - hZ * CLHEP::cm + 0.5 * thick * CLHEP::cm);
1450 G4VSolid* coolingBlock =
new G4SubtractionSolid(
"Block-Hole",
1453 G4Transform3D(rotsub,
1456 G4LogicalVolume* logicalV =
new G4LogicalVolume(coolingBlock, medCopper, logicalName, 0, 0, 0);
1460 const double phi = 360.0 / number;
1462 G4RotationMatrix rot = G4RotationMatrix();
1463 G4ThreeVector arm(cX * CLHEP::cm, cY * CLHEP::cm, cZ * CLHEP::cm - thick * CLHEP::cm / 2.0);
1466 rot.rotateZ(0.5 * phi * CLHEP::deg);
1467 arm.rotateZ(0.5 * phi * CLHEP::deg);
1469 for (
int i = 0; i < number; ++i) {
1470 const string physicalName =
"physicalRib3_" + to_string(rib3ID) +
" " + to_string(i);
1471 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
1473 rot.rotateZ(phi * CLHEP::deg);
1474 arm.rotateZ(phi * CLHEP::deg);
1479 const int nRib4s = content.getNumberNodes(
"Covers/Rib4");
1480 for (
int iRib4 = 0; iRib4 < nRib4s; ++iRib4) {
1482 rib4Content.
append((boost::format(
"/Covers/Rib4[%1%]/") % (iRib4 + 1)).str());
1483 const string srib4ID = rib4Content.
getString(
"@id");
1484 const int rib4ID = atoi(srib4ID.c_str());
1486 const double length = rib4Content.
getLength(
"Length");
1487 const double width = rib4Content.
getLength(
"Width");
1488 const double thick = rib4Content.
getLength(
"Thickness");
1489 const double length2 = rib4Content.
getLength(
"Length2");
1490 const double width2 = rib4Content.
getLength(
"Width2");
1491 const double thick2 = rib4Content.
getLength(
"Thickness2");
1492 const double cX = rib4Content.
getLength(
"PosX");
1493 const double cY = rib4Content.
getLength(
"PosY");
1494 const double cZ = rib4Content.
getLength(
"PosZ");
1495 const double hX = rib4Content.
getLength(
"HoleX");
1496 const double hY = rib4Content.
getLength(
"HoleY");
1497 const double hZ = rib4Content.
getLength(
"HoleZ");
1498 const int offset = atoi((rib4Content.
getString(
"Offset")).c_str());
1499 const int number = atoi((rib4Content.
getString(
"NDiv")).c_str());
1501 const string logicalName =
"logicalRib4" + to_string(rib4ID);
1502 G4VSolid* baseShape =
new G4Box(
"Base",
1503 0.5 * length * CLHEP::cm,
1504 0.5 * width * CLHEP::cm,
1505 0.5 * thick * CLHEP::cm);
1506 G4VSolid* sqShape =
new G4Box(
"Sq",
1507 0.5 * length2 * CLHEP::cm,
1508 0.5 * width2 * CLHEP::cm,
1509 0.5 * thick2 * CLHEP::cm);
1510 G4RotationMatrix rotsub = G4RotationMatrix();
1511 double dzc = (hZ - thick2 / 2.) - (cZ - thick / 2.);
1512 G4ThreeVector trnsub(hX * CLHEP::cm - cX * CLHEP::cm,
1513 hY * CLHEP::cm - cY * CLHEP::cm,
1515 G4VSolid* sqHoleBase =
new G4SubtractionSolid(
"Base-Sq",
1518 G4Transform3D(rotsub,
1522 G4LogicalVolume* logicalV =
new G4LogicalVolume(sqHoleBase, medCopper, logicalName, 0, 0, 0);
1524 logicalV =
new G4LogicalVolume(sqHoleBase, medNEMA_G10_Plate, logicalName, 0, 0, 0);
1528 const double phi = 360.0 / number;
1530 G4RotationMatrix rot = G4RotationMatrix();
1531 G4ThreeVector arm(cX * CLHEP::cm, cY * CLHEP::cm, cZ * CLHEP::cm - thick * CLHEP::cm / 2.0);
1534 rot.rotateZ(0.5 * phi * CLHEP::deg);
1535 arm.rotateZ(0.5 * phi * CLHEP::deg);
1537 for (
int i = 0; i < number; ++i) {
1538 const string physicalName =
"physicalRib4_" + to_string(rib4ID) +
" " + to_string(i);
1539 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
1541 rot.rotateZ(phi * CLHEP::deg);
1542 arm.rotateZ(phi * CLHEP::deg);
1547 const int nRib5s = content.getNumberNodes(
"Covers/Rib5");
1548 for (
int iRib5 = 0; iRib5 < nRib5s; ++iRib5) {
1550 rib5Content.
append((boost::format(
"/Covers/Rib5[%1%]/") % (iRib5 + 1)).str());
1551 const string srib5ID = rib5Content.
getString(
"@id");
1552 const int rib5ID = atoi(srib5ID.c_str());
1554 const double dr = rib5Content.
getLength(
"DeltaR");
1555 const double dz = rib5Content.
getLength(
"DeltaZ");
1556 const double width = rib5Content.
getLength(
"Width");
1557 const double thick = rib5Content.
getLength(
"Thickness");
1558 const double rin = rib5Content.
getLength(
"Rin");
1559 const double rotX = rib5Content.
getLength(
"RotX");
1560 const double rotY = rib5Content.
getLength(
"RotY");
1561 const double rotZ = rib5Content.
getLength(
"RotZ");
1562 const double cX = rib5Content.
getLength(
"PosX");
1563 const double cY = rib5Content.
getLength(
"PosY");
1564 const double cZ = rib5Content.
getLength(
"PosZ");
1565 const int offset = atoi((rib5Content.
getString(
"Offset")).c_str());
1566 const int number = atoi((rib5Content.
getString(
"NDiv")).c_str());
1568 const string solidName =
"solidRib5" + to_string(rib5ID);
1569 const string logicalName =
"logicalRib5" + to_string(rib5ID);
1570 const double rmax = rin + thick;
1571 const double rmin = rin;
1572 const double dphi = 2. * atan2(dz, dr);
1573 const double ddphi = thick *
tan(dphi) / rin;
1574 const double ddphi2 = width / 2. * width / 2. / (cX + dr) / rin;
1575 const double cphi = dphi - ddphi - ddphi2;
1576 G4Tubs* tubeShape =
new G4Tubs(solidName,
1579 0.5 * width * CLHEP::cm,
1583 G4LogicalVolume* logicalV =
new G4LogicalVolume(tubeShape, medAluminum, logicalName, 0, 0, 0);
1587 const double phi = 360.0 / number;
1589 G4RotationMatrix rot = G4RotationMatrix();
1592 G4ThreeVector arm(cX * CLHEP::cm, cY * CLHEP::cm, cZ * CLHEP::cm - rin * CLHEP::cm - thick * CLHEP::cm);
1598 rot.rotateZ(0.5 * phi * CLHEP::deg);
1599 arm.rotateZ(0.5 * phi * CLHEP::deg);
1601 for (
int i = 0; i < number; ++i) {
1602 const string physicalName =
"physicalRib5_" + to_string(rib5ID) +
" " + to_string(i);
1603 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
1605 rot.rotateZ(phi * CLHEP::deg);
1606 arm.rotateZ(phi * CLHEP::deg);