11 #include <cdc/geometry/GeoCDCCreator.h>
12 #include <cdc/geometry/CDCGeometryPar.h>
13 #include <cdc/geometry/CDCGeoControlPar.h>
14 #include <cdc/simulation/CDCSimControlPar.h>
15 #include <cdc/simulation/CDCSensitiveDetector.h>
16 #include <simulation/background/BkgSensitiveDetector.h>
18 #include <geometry/CreatorFactory.h>
19 #include <geometry/Materials.h>
22 #include <boost/format.hpp>
24 #include <G4Material.hh>
25 #include <G4ProductionCuts.hh>
30 #include <G4SubtractionSolid.hh>
31 #include <G4Region.hh>
32 #include <G4VSolid.hh>
34 #include <G4Polycone.hh>
36 #include <G4Colour.hh>
37 #include <G4LogicalVolume.hh>
38 #include <G4PVPlacement.hh>
39 #include <G4Transform3D.hh>
40 #include <G4VisAttributes.hh>
41 #include <G4RotationMatrix.hh>
42 #include <G4UserLimits.hh>
46 using namespace boost;
54 using namespace geometry;
62 geometry::CreatorFactory<GeoCDCCreator>
GeoCDCFactory(
"CDCCreator");
68 GeoCDCCreator::GeoCDCCreator()
72 CDCSimControlPar::getInstance();
73 CDCGeoControlPar::getInstance();
77 m_VisAttributes.clear();
78 m_VisAttributes.push_back(
new G4VisAttributes(
false));
83 GeoCDCCreator::~GeoCDCCreator()
86 if (m_bkgsensitive)
delete m_bkgsensitive;
87 for (G4VisAttributes* visAttr : m_VisAttributes)
delete visAttr;
88 m_VisAttributes.clear();
89 for (G4UserLimits* userLimits : m_userLimits)
delete userLimits;
96 m_sensitive =
new CDCSensitiveDetector(
"CDCSensitiveDetector", (2 * 24)* CLHEP::eV, 10 * CLHEP::MeV);
99 const G4double realTemperture = (273.15 + 23.) * CLHEP::kelvin;
100 G4Material* medHelium = geometry::Materials::get(
"CDCHeGas");
101 G4Material* medEthane = geometry::Materials::get(
"CDCEthaneGas");
102 G4Material* medAluminum = geometry::Materials::get(
"Al");
103 G4Material* medTungsten = geometry::Materials::get(
"W");
104 G4Material* medCFRP = geometry::Materials::get(
"CFRP");
105 G4Material* medNEMA_G10_Plate = geometry::Materials::get(
"NEMA_G10_Plate");
106 G4Material* medGlue = geometry::Materials::get(
"CDCGlue");
107 G4Material* medAir = geometry::Materials::get(
"Air");
110 G4double h2odensity = 1.000 * CLHEP::g / CLHEP::cm3;
111 G4double a = 1.01 * CLHEP::g / CLHEP::mole;
112 G4Element* elH =
new G4Element(
"Hydrogen",
"H", 1., a);
113 a = 16.00 * CLHEP::g / CLHEP::mole;
114 G4Element* elO =
new G4Element(
"Oxygen",
"O", 8., a);
115 G4Material* medH2O =
new G4Material(
"Water", h2odensity, 2);
116 medH2O->AddElement(elH, 2);
117 medH2O->AddElement(elO, 1);
118 G4Material* medCopper = geometry::Materials::get(
"Cu");
119 G4Material* medHV = geometry::Materials::get(
"CDCHVCable");
129 const double num_senseWire =
static_cast<double>(geo.
getNSenseWires());
130 const double num_fieldWire =
static_cast<double>(geo.
getNFieldWires());
131 double totalCS = M_PI * (rmin_outerWall * rmin_outerWall - rmax_innerWall * rmax_innerWall);
134 double senseCS = M_PI * (diameter_senseWire / 2) * (diameter_senseWire / 2) * num_senseWire;
137 double fieldCS = M_PI * (diameter_fieldWire / 2) * (diameter_fieldWire / 2) * num_fieldWire;
140 const double denHelium = medHelium->GetDensity() / 2.0;
141 const double denEthane = medEthane->GetDensity() / 2.0;
142 const double denAluminum = medAluminum->GetDensity() * (fieldCS / totalCS);
143 const double denTungsten = medTungsten->GetDensity() * (senseCS / totalCS);
144 const double density = denHelium + denEthane + denAluminum + denTungsten;
145 G4Material* cdcMed =
new G4Material(
"CDCGasWire", density, 4, kStateGas, realTemperture);
146 cdcMed->AddMaterial(medHelium, denHelium / density);
147 cdcMed->AddMaterial(medEthane, denEthane / density);
148 cdcMed->AddMaterial(medTungsten, denTungsten / density);
149 cdcMed->AddMaterial(medAluminum, denAluminum / density);
151 G4Material* cdcMedGas = cdcMed;
159 const double density2 = denHelium + denEthane;
160 cdcMedGas =
new G4Material(
"CDCRealGas", density2, 2, kStateGas, realTemperture);
161 cdcMedGas->AddMaterial(medHelium, denHelium / density2);
162 cdcMedGas->AddMaterial(medEthane, denEthane / density2);
166 G4cout << *(G4Material::GetMaterialTable());
170 const auto& motherRmin = mother.getRmin();
171 const auto& motherRmax = mother.getRmax();
172 const auto& motherZ = mother.getZ();
173 G4Polycone* solid_cdc =
174 new G4Polycone(
"solidCDC", 0 * CLHEP::deg, 360.* CLHEP::deg,
175 mother.getNNodes(), motherZ.data(),
176 motherRmin.data(), motherRmax.data());
177 logical_cdc =
new G4LogicalVolume(solid_cdc, medAir,
"logicalCDC", 0, 0, 0);
178 physical_cdc =
new G4PVPlacement(0, G4ThreeVector(geo.
getGlobalOffsetX() * CLHEP::cm,
181 "physicalCDC", &topVolume,
false, 0);
184 G4Region* aRegion =
new G4Region(
"CDCEnvelope");
185 logical_cdc->SetRegion(aRegion);
186 aRegion->AddRootLogicalVolume(logical_cdc);
188 m_VisAttributes.push_back(
new G4VisAttributes(
true, G4Colour(0., 1., 0.)));
190 const int iOuterWall = wall.getId();
191 const string wallName = wall.getName();
192 const double wallRmin = wall.getRmin();
193 const double wallRmax = wall.getRmax();
194 const double wallZfwd = wall.getZfwd();
195 const double wallZbwd = wall.getZbwd();
196 const double length = (wallZfwd - wallZbwd) / 2.0;
199 G4Material* medWall = medAir;
200 if (strstr((wallName).c_str(),
"MiddleWall") != NULL) {
203 medWall = medAluminum;
205 G4Tubs* outerWallTubeShape =
new G4Tubs(
"solid" + wallName, wallRmin * CLHEP::cm,
206 wallRmax * CLHEP::cm, length * CLHEP::cm, 0 * CLHEP::deg, 360.*CLHEP::deg);
208 G4LogicalVolume* outerWallTube =
new G4LogicalVolume(outerWallTubeShape, medWall,
"solid" + wallName, 0, 0, 0);
209 outerWallTube->SetVisAttributes(m_VisAttributes.back());
210 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (length + wallZbwd)*CLHEP::cm), outerWallTube,
"logical" + wallName,
211 logical_cdc,
false, iOuterWall);
215 m_VisAttributes.push_back(
new G4VisAttributes(
true, G4Colour(0., 1., 0.)));
217 const string wallName = wall.getName();
218 const double wallRmin = wall.getRmin();
219 const double wallRmax = wall.getRmax();
220 const double wallZfwd = wall.getZfwd();
221 const double wallZbwd = wall.getZbwd();
222 const double length = (wallZfwd - wallZbwd) / 2.0;
223 const int iInnerWall = wall.getId();
225 G4Material* medWall = medAir;
226 if (strstr(wallName.c_str(),
"MiddleWall") != NULL) {
228 }
else if (strstr(wallName.c_str(),
"MiddleGlue") != NULL) {
231 medWall = medAluminum;
234 G4Tubs* innerWallTubeShape =
new G4Tubs(
"solid" + wallName, wallRmin * CLHEP::cm,
235 wallRmax * CLHEP::cm, length * CLHEP::cm, 0 * CLHEP::deg, 360.*CLHEP::deg);
236 G4LogicalVolume* innerWallTube =
new G4LogicalVolume(innerWallTubeShape, medWall,
"logical" + wallName, 0, 0, 0);
237 innerWallTube->SetVisAttributes(m_VisAttributes.back());
238 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (length + wallZbwd)*CLHEP::cm), innerWallTube,
"physical" + wallName,
239 logical_cdc,
false, iInnerWall);
251 for (
int iSLayer = 0; iSLayer < nSLayer; ++iSLayer) {
255 double rmin_sensitive_left, rmax_sensitive_left;
256 double rmin_sensitive_middle, rmax_sensitive_middle;
257 double rmin_sensitive_right, rmax_sensitive_right;
258 double zback_sensitive_left, zfor_sensitive_left;
259 double zback_sensitive_middle, zfor_sensitive_middle;
260 double zback_sensitive_right, zfor_sensitive_right;
263 const auto& epLayerBwd = endplate.getEndPlateLayer(0);
264 const auto& epLayerFwd = endplate.getEndPlateLayer(nEPLayer / 2);
268 rmin_sensitive_left = epLayerBwd.getRmax();
269 rmax_sensitive_left = fieldLayer.
getR();
270 zback_sensitive_left = senseLayer.getZbwd();
271 zfor_sensitive_left = epLayerBwd.getZfwd();
273 rmin_sensitive_middle = (geo.
getInnerWall(0)).getRmax();
274 rmax_sensitive_middle = fieldLayer.getR();
275 zback_sensitive_middle = epLayerBwd.getZbwd();
276 zfor_sensitive_middle = epLayerFwd.getZbwd();
278 rmin_sensitive_right = epLayerFwd.getRmax();
279 rmax_sensitive_right = fieldLayer.getR();
280 zback_sensitive_right = epLayerFwd.getZbwd();
281 zfor_sensitive_right = senseLayer.getZfwd();
282 }
else if (iSLayer >= 1 && iSLayer <= 14) {
283 const auto& epLayerBwd = endplate.getEndPlateLayer(1);
284 const auto& epLayerFwd = endplate.getEndPlateLayer((nEPLayer / 2) + 1);
289 rmin_sensitive_left = epLayerBwd.getRmax();
290 rmax_sensitive_left = fieldLayerOut.
getR();
291 zback_sensitive_left = senseLayer.getZbwd();
292 zfor_sensitive_left = epLayerBwd.getZfwd();
294 rmin_sensitive_middle = fieldLayerIn.getR();
295 rmax_sensitive_middle = fieldLayerOut.getR();
296 zback_sensitive_middle = epLayerBwd.getZfwd();
297 zfor_sensitive_middle = epLayerFwd.getZbwd();
299 rmin_sensitive_right = epLayerFwd.getRmax();
300 rmax_sensitive_right = fieldLayerOut.getR();
301 zback_sensitive_right = epLayerFwd.getZbwd();
302 zfor_sensitive_right = senseLayer.getZfwd();
303 }
else if (iSLayer >= 15 && iSLayer <= 18) {
304 const auto& epLayerBwd = endplate.getEndPlateLayer(1);
305 const auto& epLayerFwd = endplate.getEndPlateLayer(nEPLayer / 2);
310 rmin_sensitive_left = epLayerBwd.getRmax();
311 rmax_sensitive_left = fieldLayerOut.
getR();
312 zback_sensitive_left = senseLayer.getZbwd();
313 zfor_sensitive_left = epLayerBwd.getZfwd();
315 rmin_sensitive_middle = fieldLayerIn.getR();
316 rmax_sensitive_middle = fieldLayerOut.getR();
317 zback_sensitive_middle = epLayerBwd.getZfwd();
318 zfor_sensitive_middle = epLayerFwd.getZbwd();
320 rmin_sensitive_right = epLayerFwd.getRmax();
321 rmax_sensitive_right = fieldLayerOut.getR();
322 zback_sensitive_right = epLayerFwd.getZbwd();
323 zfor_sensitive_right = senseLayer.getZfwd();
324 }
else if (iSLayer >= 19 && iSLayer < 55) {
325 const auto& epLayerBwd = endplate.getEndPlateLayer(0);
326 const auto& epLayerFwd = endplate.getEndPlateLayer(nEPLayer / 2);
331 rmin_sensitive_left = epLayerBwd.getRmax();
332 rmax_sensitive_left = fieldLayerOut.
getR();
333 zback_sensitive_left = senseLayer.getZbwd();
334 zfor_sensitive_left = epLayerBwd.getZfwd();
336 rmin_sensitive_middle = fieldLayerIn.getR();
337 rmax_sensitive_middle = fieldLayerOut.getR();
338 zback_sensitive_middle = epLayerBwd.getZfwd();
339 zfor_sensitive_middle = epLayerFwd.getZbwd();
341 rmin_sensitive_right = epLayerFwd.getRmax();
342 rmax_sensitive_right = fieldLayerOut.getR();
343 zback_sensitive_right = epLayerFwd.getZbwd();
344 zfor_sensitive_right = senseLayer.getZfwd();
346 }
else if (iSLayer == 55) {
348 const auto& epLayerBwdIn = endplate.getEndPlateLayer(0);
349 const auto& epLayerBwdOut = endplate.getEndPlateLayer((nEPLayer / 2) - 1);
350 const auto& epLayerFwdIn = endplate.getEndPlateLayer(nEPLayer / 2);
351 const auto& epLayerFwdOut = endplate.getEndPlateLayer(nEPLayer - 1);
354 int iSLayerMinus1 = iSLayer - 1;
356 rmin_sensitive_left = epLayerBwdIn.getRmax();
357 rmax_sensitive_left = epLayerBwdOut.getRmax();
358 zback_sensitive_left = senseLayer.
getZbwd();
359 zfor_sensitive_left = epLayerBwdIn.getZfwd();
361 rmin_sensitive_middle = fieldLayerIn.getR();
362 rmax_sensitive_middle = (geo.
getOuterWall(0)).getRmin();
363 zback_sensitive_middle = epLayerBwdIn.getZfwd();
364 zfor_sensitive_middle = epLayerFwdIn.getZbwd();
366 rmin_sensitive_right = epLayerFwdIn.getRmax();
367 rmax_sensitive_right = epLayerFwdOut.getRmax();
368 zback_sensitive_right = epLayerFwdIn.getZbwd();
369 zfor_sensitive_right = senseLayer.getZfwd();
372 B2ERROR(
"Undefined sensitive layer : " << iSLayer);
378 if ((zfor_sensitive_left - zback_sensitive_left) > length_feedthrough) {
395 G4Tubs* leftTubeShape =
new G4Tubs((format(
"solidCDCLayer_%1%_leftTube") % iSLayer).str().c_str(), rmin_sensitive_left * CLHEP::cm,
396 rmax_sensitive_left * CLHEP::cm, length_feedthrough * CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
397 G4LogicalVolume* leftTube =
new G4LogicalVolume(leftTubeShape, cdcMed,
398 (format(
"logicalCDCLayer_%1%_leftTube") % iSLayer).str().c_str(), 0, 0, 0);
399 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zback_sensitive_left + length_feedthrough / 2.0)*CLHEP::cm), leftTube,
400 (format(
"physicalCDCLayer_%1%_leftTube") % iSLayer).str().c_str(), logical_cdc,
false, iSLayer);
402 G4Tubs* leftSensitiveTubeShape =
new G4Tubs((format(
"solidSD_CDCLayer_%1%_left") % iSLayer).str().c_str(),
403 rmin_sensitive_left * CLHEP::cm, rmax_sensitive_left * CLHEP::cm,
404 (zfor_sensitive_left - zback_sensitive_left - length_feedthrough)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
405 G4LogicalVolume* leftSensitiveTube =
new G4LogicalVolume(leftSensitiveTubeShape, cdcMed,
406 (format(
"logicalSD_CDCLayer_%1%_left") % iSLayer).str().c_str(), 0, 0, 0);
407 leftSensitiveTube->SetSensitiveDetector(m_sensitive);
408 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfor_sensitive_left + zback_sensitive_left + length_feedthrough)*CLHEP::cm / 2.0),
409 leftSensitiveTube, (format(
"physicalSD_CDCLayer_%1%_left") % iSLayer).str().c_str(), logical_cdc,
false, iSLayer);
427 G4Tubs* leftTubeShape =
new G4Tubs((format(
"solidCDCLayer_%1%_leftTube") % iSLayer).str().c_str(), rmin_sensitive_left * CLHEP::cm,
428 rmax_sensitive_left * CLHEP::cm, (zfor_sensitive_left - zback_sensitive_left)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
429 G4LogicalVolume* leftTube =
new G4LogicalVolume(leftTubeShape, cdcMed,
430 (format(
"logicalCDCLayer_%1%_leftTube") % iSLayer).str().c_str(), 0, 0, 0);
431 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfor_sensitive_left + zback_sensitive_left)*CLHEP::cm / 2.0), leftTube,
432 (format(
"physicalCDCLayer_%1%_leftTube") % iSLayer).str().c_str(), logical_cdc,
false, iSLayer);
436 G4Tubs* leftMidTubeShape =
new G4Tubs((format(
"solidCDCLayer_%1%_leftMidTube") % iSLayer).str().c_str(),
437 rmin_sensitive_middle * CLHEP::cm, rmax_sensitive_middle * CLHEP::cm,
438 (length_feedthrough - zfor_sensitive_left + zback_sensitive_left)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
439 G4LogicalVolume* leftMidTube =
new G4LogicalVolume(leftMidTubeShape, cdcMed,
440 (format(
"logicalCDCLayer_%1%_leftMidTube") % iSLayer).str().c_str(), 0, 0, 0);
442 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (length_feedthrough + zfor_sensitive_left + zback_sensitive_left)*CLHEP::cm / 2.0),
443 leftMidTube, (format(
"physicalCDCLayer_%1%_leftMidTube") % iSLayer).str().c_str(), logical_cdc,
false, iSLayer);
446 zback_sensitive_middle = length_feedthrough + zback_sensitive_left;
450 if ((zfor_sensitive_right - zback_sensitive_right) > length_feedthrough) {
467 G4Tubs* rightTubeShape =
new G4Tubs((format(
"solidCDCLayer_%1%_rightTube") % iSLayer).str().c_str(),
468 rmin_sensitive_right * CLHEP::cm, rmax_sensitive_right * CLHEP::cm, length_feedthrough * CLHEP::cm / 2.0, 0 * CLHEP::deg,
470 G4LogicalVolume* rightTube =
new G4LogicalVolume(rightTubeShape, cdcMed,
471 (format(
"logicalCDCLayer_%1%_rightTube") % iSLayer).str().c_str(), 0, 0, 0);
473 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfor_sensitive_right - length_feedthrough / 2.0)*CLHEP::cm), rightTube,
474 (format(
"physicalCDCLayer_%1%_rightTube") % iSLayer).str().c_str(), logical_cdc,
false, iSLayer);
478 G4Tubs* rightSensitiveTubeShape =
new G4Tubs((format(
"solidSD_CDCLayer_%1%_right") % iSLayer).str().c_str(),
479 rmin_sensitive_right * CLHEP::cm, rmax_sensitive_right * CLHEP::cm,
480 (zfor_sensitive_right - zback_sensitive_right - length_feedthrough)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
481 G4LogicalVolume* rightSensitiveTube =
new G4LogicalVolume(rightSensitiveTubeShape, cdcMed,
482 (format(
"logicalSD_CDCLayer_%1%_right") % iSLayer).str().c_str(), 0, 0, 0);
483 rightSensitiveTube->SetSensitiveDetector(m_sensitive);
485 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfor_sensitive_right + zback_sensitive_right - length_feedthrough)*CLHEP::cm / 2.0),
486 rightSensitiveTube, (format(
"physicalSD_CDCLayer_%1%_right") % iSLayer).str().c_str(), logical_cdc,
false, iSLayer);
505 G4Tubs* rightTubeShape =
new G4Tubs((format(
"solidCDCLayer_%1%_rightTube") % iSLayer).str().c_str(),
506 rmin_sensitive_right * CLHEP::cm, rmax_sensitive_right * CLHEP::cm, (zfor_sensitive_right - zback_sensitive_right)*CLHEP::cm / 2.0,
507 0 * CLHEP::deg, 360.*CLHEP::deg);
508 G4LogicalVolume* rightTube =
new G4LogicalVolume(rightTubeShape, cdcMed,
509 (format(
"logicalCDCLayer_%1%_rightTube") % iSLayer).str().c_str(), 0, 0, 0);
511 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfor_sensitive_right + zback_sensitive_right)*CLHEP::cm / 2.0), rightTube,
512 (format(
"physicalCDCLayer_%1%_rightTube") % iSLayer).str().c_str(), logical_cdc,
false, iSLayer);
516 G4Tubs* rightMidTubeShape =
new G4Tubs((format(
"solidCDCLayer_%1%_rightMidTube") % iSLayer).str().c_str(),
517 rmin_sensitive_middle * CLHEP::cm, rmax_sensitive_middle * CLHEP::cm,
518 (length_feedthrough - zfor_sensitive_right + zback_sensitive_right)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
519 G4LogicalVolume* rightMidTube =
new G4LogicalVolume(rightMidTubeShape, cdcMed,
520 (format(
"logicalCDCLayer_%1%_rightMidTube") % iSLayer).str().c_str(), 0, 0, 0);
521 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zback_sensitive_right - length_feedthrough + zfor_sensitive_right)*CLHEP::cm / 2.0),
522 rightMidTube, (format(
"physicalCDCLayer_%1%_rightMidTube") % iSLayer).str().c_str(), logical_cdc,
false, iSLayer);
525 zfor_sensitive_middle = zfor_sensitive_right - length_feedthrough;
530 G4Tubs* middleSensitiveTubeShape =
new G4Tubs((format(
"solidSD_CDCLayer_%1%_middle") % iSLayer).str().c_str(),
531 rmin_sensitive_middle * CLHEP::cm, rmax_sensitive_middle * CLHEP::cm,
532 (zfor_sensitive_middle - zback_sensitive_middle)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
533 G4LogicalVolume* middleSensitiveTube =
new G4LogicalVolume(middleSensitiveTubeShape, cdcMedGas,
534 (format(
"logicalSD_CDCLayer_%1%_middle") % iSLayer).str().c_str(), 0, 0, 0);
537 G4UserLimits* uLimits =
new G4UserLimits(8.5 * CLHEP::cm);
538 m_userLimits.push_back(uLimits);
539 middleSensitiveTube->SetUserLimits(uLimits);
540 middleSensitiveTube->SetSensitiveDetector(m_sensitive);
542 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfor_sensitive_middle + zback_sensitive_middle)*CLHEP::cm / 2.0), middleSensitiveTube,
543 (format(
"physicalSD_CDCLayer_%1%_middle") % iSLayer).str().c_str(), logical_cdc,
false, iSLayer);
547 G4String sName =
"sWire";
552 G4double tAtZ0 = -wb0.Z() / (wf0.Z() - wb0.Z());
553 TVector3 wAtZ0 = wb0 + tAtZ0 * (wf0 - wb0);
555 const G4double epsl = 25.e-4;
556 G4double reductionBwd = (zback_sensitive_middle + epsl) / wb0.Z();
558 wb0 = reductionBwd * (wb0 - wAtZ0) + wAtZ0;
560 G4double reductionFwd = (zfor_sensitive_middle - epsl) / wf0.Z();
561 wf0 = reductionFwd * (wf0 - wAtZ0) + wAtZ0;
563 const G4double wireHalfLength = 0.5 * (wf0 - wb0).Mag() * CLHEP::cm;
566 G4Tubs* middleSensitiveSwireShape =
new G4Tubs(sName, 0., sWireRadius, wireHalfLength, 0., 360. * CLHEP::deg);
567 G4LogicalVolume* middleSensitiveSwire =
new G4LogicalVolume(middleSensitiveSwireShape, medTungsten, sName);
569 middleSensitiveSwire->SetVisAttributes(m_VisAttributes.front());
571 G4String fName =
"fWire";
573 G4Tubs* middleSensitiveFwireShape =
new G4Tubs(fName, 0., fWireRadius, wireHalfLength, 0., 360. * CLHEP::deg);
574 G4LogicalVolume* middleSensitiveFwire =
new G4LogicalVolume(middleSensitiveFwireShape, medAluminum, fName);
576 middleSensitiveFwire->SetVisAttributes(m_VisAttributes.front());
581 const G4double dphi = M_PI / nCells;
582 const TVector3 unitZ(0., 0., 1.);
584 for (
int ic = 0; ic < nCells; ++ic) {
588 G4double tAtZ02 = -wb.Z() / (wf.Z() - wb.Z());
589 TVector3 wAtZ02 = wb + tAtZ02 * (wf - wb);
590 G4double reductionBwd2 = (zback_sensitive_middle + epsl) / wb.Z();
591 wb = reductionBwd2 * (wb - wAtZ02) + wAtZ02;
592 G4double reductionFwd2 = (zfor_sensitive_middle - epsl) / wf.Z();
593 wf = reductionFwd2 * (wf - wAtZ02) + wAtZ02;
595 G4double thetaYZ = -asin((wf - wb).Y() / (wf - wb).Mag());
597 TVector3 fMinusBInZX((wf - wb).X(), 0., (wf - wb).Z());
598 G4double thetaZX = asin((unitZ.Cross(fMinusBInZX)).Y() / fMinusBInZX.Mag());
599 G4RotationMatrix rotM;
601 rotM.rotateX(thetaYZ * CLHEP::rad);
602 rotM.rotateY(thetaZX * CLHEP::rad);
604 G4ThreeVector xyz(0.5 * (wb.X() + wf.X()) * CLHEP::cm,
605 0.5 * (wb.Y() + wf.Y()) * CLHEP::cm, 0.);
609 new G4PVPlacement(G4Transform3D(rotM, xyz), middleSensitiveSwire, sName, middleSensitiveTube,
false, ic);
613 G4double rF = rmax_sensitive_middle - 0.5 * diameter;
615 G4double phi = atan2(wbF.Y(), wbF.X());
616 wbF.SetX(rF * cos(phi));
617 wbF.SetY(rF * sin(phi));
620 rF = rmax_sensitive_middle - 0.5 * diameter;
621 phi = atan2(wfF.Y(), wfF.X());
622 wfF.SetX(rF * cos(phi));
623 wfF.SetY(rF * sin(phi));
625 thetaYZ = -asin((wfF - wbF).Y() / (wfF - wbF).Mag());
627 fMinusBInZX = wfF - wbF;
628 fMinusBInZX.SetY(0.);
629 thetaZX = asin((unitZ.Cross(fMinusBInZX)).Y() / fMinusBInZX.Mag());
631 G4RotationMatrix rotM1;
632 rotM1.rotateX(thetaYZ * CLHEP::rad);
633 rotM1.rotateY(thetaZX * CLHEP::rad);
635 xyz.setX(0.5 * (wbF.X() + wfF.X()) * CLHEP::cm);
636 xyz.setY(0.5 * (wbF.Y() + wfF.Y()) * CLHEP::cm);
638 if (iSLayer != nSLayer - 1) {
640 new G4PVPlacement(G4Transform3D(rotM1, xyz), middleSensitiveFwire, fName, middleSensitiveTube,
false, ic);
646 phi = atan2(wbF.Y(), wbF.X());
647 wbF.SetX(rF * cos(phi + dphi));
648 wbF.SetY(rF * sin(phi + dphi));
652 phi = atan2(wfF.Y(), wfF.X());
653 wfF.SetX(rF * cos(phi + dphi));
654 wfF.SetY(rF * sin(phi + dphi));
656 thetaYZ = -asin((wfF - wbF).Y() / (wfF - wbF).Mag());
658 fMinusBInZX = wfF - wbF;
659 fMinusBInZX.SetY(0.);
660 thetaZX = asin((unitZ.Cross(fMinusBInZX)).Y() / fMinusBInZX.Mag());
662 G4RotationMatrix rotM2;
663 rotM2.rotateX(thetaYZ * CLHEP::rad);
664 rotM2.rotateY(thetaZX * CLHEP::rad);
666 xyz.setX(0.5 * (wbF.X() + wfF.X()) * CLHEP::cm);
667 xyz.setY(0.5 * (wbF.Y() + wfF.Y()) * CLHEP::cm);
670 new G4PVPlacement(G4Transform3D(rotM2, xyz), middleSensitiveFwire, fName, middleSensitiveTube,
false, ic + nCells);
674 rF = rmax_sensitive_middle - 0.5 * diameter;
675 phi = atan2(wbF.Y(), wbF.X());
676 wbF.SetX(rF * cos(phi + dphi));
677 wbF.SetY(rF * sin(phi + dphi));
680 rF = rmax_sensitive_middle - 0.5 * diameter;
681 phi = atan2(wfF.Y(), wfF.X());
682 wfF.SetX(rF * cos(phi + dphi));
683 wfF.SetY(rF * sin(phi + dphi));
685 thetaYZ = -asin((wfF - wbF).Y() / (wfF - wbF).Mag());
687 fMinusBInZX = wfF - wbF;
688 fMinusBInZX.SetY(0.);
689 thetaZX = asin((unitZ.Cross(fMinusBInZX)).Y() / fMinusBInZX.Mag());
691 G4RotationMatrix rotM3;
692 rotM3.rotateX(thetaYZ * CLHEP::rad);
693 rotM3.rotateY(thetaZX * CLHEP::rad);
695 xyz.setX(0.5 * (wbF.X() + wfF.X()) * CLHEP::cm);
696 xyz.setY(0.5 * (wbF.Y() + wfF.Y()) * CLHEP::cm);
698 if (iSLayer != nSLayer - 1) {
699 new G4PVPlacement(G4Transform3D(rotM3, xyz), middleSensitiveFwire, fName, middleSensitiveTube,
false, ic + 2 * nCells);
709 m_VisAttributes.push_back(
new G4VisAttributes(
true, G4Colour(1., 1., 0.)));
711 for (
const auto& epLayer : endplate.getEndPlateLayers()) {
712 const int iEPLayer = epLayer.getILayer();
713 const string name = epLayer.getName();
714 const double rmin = epLayer.getRmin();
715 const double rmax = epLayer.getRmax();
716 const double zbwd = epLayer.getZbwd();
717 const double zfwd = epLayer.getZfwd();
718 const double length = (zfwd - zbwd) / 2.0;
720 G4Tubs* tube =
new G4Tubs(
"solidCDCEndplate" + name, rmin * CLHEP::cm,
721 rmax * CLHEP::cm, length * CLHEP::cm, 0 * CLHEP::deg, 360.*CLHEP::deg);
722 G4LogicalVolume* logical =
new G4LogicalVolume(tube, Materials::get(
"G4_Al"),
723 "logicalCDCEndplate" + name, 0, 0);
724 logical->SetVisAttributes(m_VisAttributes.back());
725 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfwd + zbwd)*CLHEP::cm / 2.0), logical,
726 "physicalCDCEndplate" + name, logical_cdc,
false, iEPLayer);
734 const int iEB = frontend.getId();
735 const double ebInnerR = frontend.getRmin();
736 const double ebOuterR = frontend.getRmax();
737 const double ebBZ = frontend.getZbwd();
738 const double ebFZ = frontend.getZfwd();
740 G4Tubs* ebTubeShape =
new G4Tubs((format(
"solidSD_ElectronicsBoard_Layer%1%") % iEB).str().c_str(), ebInnerR * CLHEP::cm,
741 ebOuterR * CLHEP::cm, (ebFZ - ebBZ)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
743 G4LogicalVolume* ebTube =
new G4LogicalVolume(ebTubeShape, medNEMA_G10_Plate,
744 (format(
"logicalSD_ElectronicsBoard_Layer%1%") % iEB).str().c_str(), 0, 0, 0);
746 ebTube->SetSensitiveDetector(m_bkgsensitive);
747 ebTube->SetVisAttributes(m_VisAttributes.back());
748 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (ebFZ + ebBZ)*CLHEP::cm / 2.0), ebTube,
749 (format(
"physicalSD_ElectronicsBoard_Layer%1%") % iEB).str().c_str(), logical_cdc,
false, iEB);
755 createNeutronShields(geo);
770 for (
const auto& rib : geo.
getRibs()) {
772 const int id = rib.getId();
773 const double length = rib.getLength();
774 const double width = rib.getWidth();
775 const double thick = rib.getThick();
776 const double rotx = rib.getRotX();
777 const double roty = rib.getRotY();
778 const double rotz = rib.getRotZ();
779 const double x = rib.getX();
780 const double y = rib.getY();
781 const double z = rib.getZ();
782 const int offset = rib.getOffset();
783 const int ndiv = rib.getNDiv();
785 const string solidName =
"solidRib" + to_string(
id);
786 const string logicalName =
"logicalRib" + to_string(
id);
787 G4Box* boxShape =
new G4Box(solidName, 0.5 * length * CLHEP::cm,
788 0.5 * width * CLHEP::cm,
789 0.5 * thick * CLHEP::cm);
791 const double rmax = 0.5 * length;
792 const double rmin = max((rmax - thick), 0.);
793 G4Tubs* tubeShape =
new G4Tubs(solidName,
796 0.5 * width * CLHEP::cm,
803 G4LogicalVolume* logicalV =
new G4LogicalVolume(boxShape, medAluminum, logicalName, 0, 0, 0);
804 if (
id > 39 &&
id < 78)
805 logicalV =
new G4LogicalVolume(boxShape, medCopper, logicalName, 0, 0, 0);
806 if ((
id > 77 &&
id < 94) || (
id > 131 &&
id < 146))
807 logicalV =
new G4LogicalVolume(boxShape, medNEMA_G10_Plate, logicalName, 0, 0, 0);
808 if (
id > 93 &&
id < 110)
809 logicalV =
new G4LogicalVolume(tubeShape, medCopper, logicalName, 0, 0, 0);
810 if (
id > 109 &&
id < 126)
811 logicalV =
new G4LogicalVolume(tubeShape, medH2O, logicalName, 0, 0, 0);
812 if (
id > 127 &&
id < 132)
813 logicalV =
new G4LogicalVolume(boxShape, medHV, logicalName, 0, 0, 0);
821 logicalV->SetVisAttributes(m_VisAttributes.back());
823 const double phi = 360.0 / ndiv;
825 G4RotationMatrix rot = G4RotationMatrix();
827 if (
id > 93 &&
id < 126) dz = 0;
829 G4ThreeVector arm(x * CLHEP::cm, y * CLHEP::cm, z * CLHEP::cm - dz * CLHEP::cm / 2.0);
834 rot.rotateZ(0.5 * phi * CLHEP::deg);
835 arm.rotateZ(0.5 * phi * CLHEP::deg);
837 for (
int i = 0; i < ndiv; ++i) {
838 const string physicalName =
"physicalRib_" + to_string(
id) +
" " + to_string(i);
839 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
840 physicalName.c_str(), logical_cdc,
false,
id);
841 rot.rotateZ(phi * CLHEP::deg);
842 arm.rotateZ(phi * CLHEP::deg);
850 for (
const auto& rib2 : geo.
getRib2s()) {
852 const int id = rib2.getId();
853 const double length = rib2.getLength();
854 const double width = rib2.getWidth();
855 const double thick = rib2.getThick();
856 const double width2 = rib2.getWidth2();
857 const double thick2 = rib2.getThick2();
858 const double rotx = rib2.getRotX();
859 const double roty = rib2.getRotY();
860 const double rotz = rib2.getRotZ();
861 const double x = rib2.getX();
862 const double y = rib2.getY();
863 const double z = rib2.getZ();
864 const int ndiv = rib2.getNDiv();
866 const string solidName =
"solidRib2" + to_string(
id);
867 const string logicalName =
"logicalRib2" + to_string(
id);
868 G4Trd* trdShape =
new G4Trd(solidName,
869 0.5 * thick * CLHEP::cm,
870 0.5 * thick2 * CLHEP::cm,
871 0.5 * width * CLHEP::cm,
872 0.5 * width2 * CLHEP::cm,
873 0.5 * length * CLHEP::cm);
875 G4LogicalVolume* logicalV =
new G4LogicalVolume(trdShape, medAluminum, logicalName, 0, 0, 0);
878 logicalV =
new G4LogicalVolume(trdShape, medCopper, logicalName, 0, 0, 0);
880 logicalV->SetVisAttributes(m_VisAttributes.back());
882 const double phi = 360.0 / ndiv;
884 G4RotationMatrix rot = G4RotationMatrix();
885 G4ThreeVector arm(x * CLHEP::cm, y * CLHEP::cm, z * CLHEP::cm - thick * CLHEP::cm / 2.0);
890 for (
int i = 0; i < ndiv; ++i) {
891 const string physicalName =
"physicalRib2_" + to_string(
id) +
" " + to_string(i);
892 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
893 physicalName.c_str(), logical_cdc,
false,
id);
894 rot.rotateZ(phi * CLHEP::deg);
895 arm.rotateZ(phi * CLHEP::deg);
903 for (
const auto& rib3 : geo.
getRib3s()) {
905 const int id = rib3.getId();
906 const double length = rib3.getLength();
907 const double width = rib3.getWidth();
908 const double thick = rib3.getThick();
909 const double r = rib3.getR();
910 const double x = rib3.getX();
911 const double y = rib3.getY();
912 const double z = rib3.getZ();
913 const double rx = rib3.getRx();
914 const double ry = rib3.getRy();
915 const double rz = rib3.getRz();
916 const int offset = rib3.getOffset();
917 const int ndiv = rib3.getNDiv();
919 const string logicalName =
"logicalRib3" + to_string(
id);
920 G4VSolid* boxShape =
new G4Box(
"Block",
921 0.5 * length * CLHEP::cm,
922 0.5 * width * CLHEP::cm,
923 0.5 * thick * CLHEP::cm);
924 G4VSolid* tubeShape =
new G4Tubs(
"Hole",
931 G4RotationMatrix rotsub = G4RotationMatrix();
932 rotsub.rotateX(90. * CLHEP::deg);
933 G4ThreeVector trnsub(rx * CLHEP::cm - x * CLHEP::cm, ry * CLHEP::cm - y * CLHEP::cm,
934 rz * CLHEP::cm - z * CLHEP::cm + 0.5 * thick * CLHEP::cm);
935 G4VSolid* coolingBlock =
new G4SubtractionSolid(
"Block-Hole",
938 G4Transform3D(rotsub,
941 G4LogicalVolume* logicalV =
new G4LogicalVolume(coolingBlock, medCopper, logicalName, 0, 0, 0);
943 logicalV->SetVisAttributes(m_VisAttributes.back());
945 const double phi = 360.0 / ndiv;
947 G4RotationMatrix rot = G4RotationMatrix();
948 G4ThreeVector arm(x * CLHEP::cm, y * CLHEP::cm, z * CLHEP::cm - thick * CLHEP::cm / 2.0);
951 rot.rotateZ(0.5 * phi * CLHEP::deg);
952 arm.rotateZ(0.5 * phi * CLHEP::deg);
954 for (
int i = 0; i < ndiv; ++i) {
955 const string physicalName =
"physicalRib3_" + to_string(
id) +
" " + to_string(i);
956 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
957 physicalName.c_str(), logical_cdc,
false,
id);
958 rot.rotateZ(phi * CLHEP::deg);
959 arm.rotateZ(phi * CLHEP::deg);
967 for (
const auto& rib4 : geo.
getRib4s()) {
969 const int id = rib4.getId();
970 const double length = rib4.getLength();
971 const double width = rib4.getWidth();
972 const double thick = rib4.getThick();
973 const double length2 = rib4.getLength2();
974 const double width2 = rib4.getWidth2();
975 const double thick2 = rib4.getThick2();
976 const double x = rib4.getX();
977 const double y = rib4.getY();
978 const double z = rib4.getZ();
979 const double x2 = rib4.getX2();
980 const double y2 = rib4.getY2();
981 const double z2 = rib4.getZ2();
982 const int offset = rib4.getOffset();
983 const int ndiv = rib4.getNDiv();
985 const string logicalName =
"logicalRib4" + to_string(
id);
986 G4VSolid* baseShape =
new G4Box(
"Base",
987 0.5 * length * CLHEP::cm,
988 0.5 * width * CLHEP::cm,
989 0.5 * thick * CLHEP::cm);
990 G4VSolid* sqShape =
new G4Box(
"Sq",
991 0.5 * length2 * CLHEP::cm,
992 0.5 * width2 * CLHEP::cm,
993 0.5 * thick2 * CLHEP::cm);
995 G4RotationMatrix rotsub = G4RotationMatrix();
996 double dzc = (z2 - thick2 / 2.) - (z - thick / 2.);
997 G4ThreeVector trnsub(x2 * CLHEP::cm - x * CLHEP::cm,
998 y2 * CLHEP::cm - y * CLHEP::cm,
1000 G4VSolid* sqHoleBase =
new G4SubtractionSolid(
"Box-Sq",
1003 G4Transform3D(rotsub,
1007 G4LogicalVolume* logicalV =
new G4LogicalVolume(sqHoleBase, medCopper, logicalName, 0, 0, 0);
1009 logicalV =
new G4LogicalVolume(sqHoleBase, medNEMA_G10_Plate, logicalName, 0, 0, 0);
1011 logicalV->SetVisAttributes(m_VisAttributes.back());
1013 const double phi = 360.0 / ndiv;
1015 G4RotationMatrix rot = G4RotationMatrix();
1016 G4ThreeVector arm(x * CLHEP::cm, y * CLHEP::cm, z * CLHEP::cm - thick * CLHEP::cm / 2.0);
1019 rot.rotateZ(0.5 * phi * CLHEP::deg);
1020 arm.rotateZ(0.5 * phi * CLHEP::deg);
1022 for (
int i = 0; i < ndiv; ++i) {
1023 const string physicalName =
"physicalRib4_" + to_string(
id) +
" " + to_string(i);
1024 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
1025 physicalName.c_str(), logical_cdc,
false,
id);
1026 rot.rotateZ(phi * CLHEP::deg);
1027 arm.rotateZ(phi * CLHEP::deg);
1035 for (
const auto& rib5 : geo.
getRib5s()) {
1037 const int id = rib5.getId();
1038 const double dr = rib5.getDr();
1039 const double dz = rib5.getDz();
1040 const double width = rib5.getWidth();
1041 const double thick = rib5.getThick();
1042 const double rin = rib5.getRin();
1043 const double x = rib5.getX();
1044 const double y = rib5.getY();
1045 const double z = rib5.getZ();
1046 const double rotx = rib5.getRotx();
1047 const double roty = rib5.getRoty();
1048 const double rotz = rib5.getRotz();
1049 const int offset = rib5.getOffset();
1050 const int ndiv = rib5.getNDiv();
1052 const string solidName =
"solidRib5" + to_string(
id);
1053 const string logicalName =
"logicalRib5" + to_string(
id);
1055 const double rmax = rin + thick;
1056 const double rmin = rin;
1057 const double dphi = 2. * atan2(dz, dr);
1058 const double ddphi = thick * tan(dphi) / rin;
1059 const double ddphi2 = width / 2. * width / 2. / (x + dr) / rin;
1060 const double cphi = dphi - ddphi - ddphi2;
1061 G4Tubs* tubeShape =
new G4Tubs(solidName,
1064 0.5 * width * CLHEP::cm,
1068 G4LogicalVolume* logicalV =
new G4LogicalVolume(tubeShape, medAluminum, logicalName, 0, 0, 0);
1070 logicalV->SetVisAttributes(m_VisAttributes.back());
1072 const double phi = 360.0 / ndiv;
1074 G4RotationMatrix rot = G4RotationMatrix();
1077 G4ThreeVector arm(x * CLHEP::cm, y * CLHEP::cm, z * CLHEP::cm - rin * CLHEP::cm - thick * CLHEP::cm);
1082 rot.rotateZ(0.5 * phi * CLHEP::deg);
1083 arm.rotateZ(0.5 * phi * CLHEP::deg);
1085 for (
int i = 0; i < ndiv; ++i) {
1086 const string physicalName =
"physicalRib5_" + to_string(
id) +
" " + to_string(i);
1087 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
1088 physicalName.c_str(), logical_cdc,
false,
id);
1089 rot.rotateZ(phi * CLHEP::deg);
1090 arm.rotateZ(phi * CLHEP::deg);
1096 createMapper(topVolume);
1100 void GeoCDCCreator::createNeutronShields(
const GearDir& content)
1103 G4Material* C2H4 = geometry::Materials::get(
"G4_POLYETHYLENE");
1104 G4Material* elB = geometry::Materials::get(
"G4_B");
1108 G4Material* boratedpoly05 =
new G4Material(
"BoratedPoly05", 1.06 * CLHEP::g / CLHEP::cm3, 2);
1109 boratedpoly05->AddMaterial(elB, 0.05);
1110 boratedpoly05->AddMaterial(C2H4, 0.95);
1112 G4Material* boratedpoly30 =
new G4Material(
"BoratedPoly30", 1.19 * CLHEP::g / CLHEP::cm3, 2);
1113 boratedpoly30->AddMaterial(elB, 0.30);
1114 boratedpoly30->AddMaterial(C2H4, 0.70);
1116 G4Material* shieldMat = C2H4;
1118 const int nShields = content.getNumberNodes(
"Shields/Shield");
1120 for (
int iShield = 0; iShield < nShields; ++iShield) {
1121 GearDir shieldContent(content);
1122 shieldContent.
append((format(
"/Shields/Shield[%1%]/") % (iShield + 1)).str());
1123 const string sShieldID = shieldContent.
getString(
"@id");
1124 const int shieldID = atoi(sShieldID.c_str());
1126 const double shieldInnerR1 = shieldContent.
getLength(
"InnerR1");
1127 const double shieldInnerR2 = shieldContent.
getLength(
"InnerR2");
1128 const double shieldOuterR1 = shieldContent.
getLength(
"OuterR1");
1129 const double shieldOuterR2 = shieldContent.
getLength(
"OuterR2");
1130 const double shieldThick = shieldContent.
getLength(
"Thickness");
1131 const double shieldPosZ = shieldContent.
getLength(
"PosZ");
1133 G4Cons* shieldConsShape =
new G4Cons((format(
"solidShield%1%") % shieldID).str().c_str(),
1134 shieldInnerR1 * CLHEP::cm, shieldOuterR1 * CLHEP::cm,
1135 shieldInnerR2 * CLHEP::cm, shieldOuterR2 * CLHEP::cm,
1136 shieldThick * CLHEP::cm / 2.0,
1137 0.*CLHEP::deg, 360.*CLHEP::deg);
1139 G4LogicalVolume* shieldCons =
new G4LogicalVolume(shieldConsShape, shieldMat, (format(
"logicalShield%1%") % shieldID).str().c_str(),
1141 shieldCons->SetVisAttributes(m_VisAttributes.back());
1142 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (shieldPosZ - shieldThick / 2.0) * CLHEP::cm), shieldCons,
1143 (format(
"physicalShield%1%") % shieldID).str().c_str(), logical_cdc,
false, 0);
1153 G4Material* C2H4 = geometry::Materials::get(
"G4_POLYETHYLENE");
1154 G4Material* shieldMat = C2H4;
1156 for (
const auto& shield : geom.getNeutronShields()) {
1157 const int shieldID = shield.getId();
1158 const double shieldInnerR1 = shield.getRmin1();
1159 const double shieldInnerR2 = shield.getRmin2();
1160 const double shieldOuterR1 = shield.getRmax1();
1161 const double shieldOuterR2 = shield.getRmax2();
1162 const double shieldThick = shield.getThick();
1163 const double shieldPosZ = shield.getZ();
1165 G4Cons* shieldConsShape =
new G4Cons(
"solidShield" + to_string(shieldID),
1166 shieldInnerR1 * CLHEP::cm, shieldOuterR1 * CLHEP::cm,
1167 shieldInnerR2 * CLHEP::cm, shieldOuterR2 * CLHEP::cm,
1168 shieldThick * CLHEP::cm / 2.0,
1169 0.*CLHEP::deg, 360.*CLHEP::deg);
1171 G4LogicalVolume* shieldCons =
new G4LogicalVolume(shieldConsShape, shieldMat,
"logicalShield" + to_string(shieldID),
1173 shieldCons->SetVisAttributes(m_VisAttributes.back());
1174 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (shieldPosZ - shieldThick / 2.0) * CLHEP::cm), shieldCons,
1175 "physicalShield" + to_string(shieldID), logical_cdc,
false, 0);
1181 void GeoCDCCreator::createCovers(
const GearDir& content)
1183 string Aluminum = content.getString(
"Aluminum");
1184 G4Material* medAluminum = geometry::Materials::get(Aluminum);
1185 G4Material* medNEMA_G10_Plate = geometry::Materials::get(
"NEMA_G10_Plate");
1187 G4double density = 1.000 * CLHEP::g / CLHEP::cm3;
1188 G4double a = 1.01 * CLHEP::g / CLHEP::mole;
1189 G4Element* elH =
new G4Element(
"Hydrogen",
"H", 1., a);
1190 a = 16.00 * CLHEP::g / CLHEP::mole;
1191 G4Element* elO =
new G4Element(
"Oxygen",
"O", 8., a);
1192 G4Material* medH2O =
new G4Material(
"Water", density, 2);
1193 medH2O->AddElement(elH, 2);
1194 medH2O->AddElement(elO, 1);
1195 G4Material* medCopper = geometry::Materials::get(
"Cu");
1196 G4Material* medLV = geometry::Materials::get(
"CDCLVCable");
1197 G4Material* medFiber = geometry::Materials::get(
"CDCOpticalFiber");
1198 G4Material* medCAT7 = geometry::Materials::get(
"CDCCAT7");
1199 G4Material* medTRG = geometry::Materials::get(
"CDCOpticalFiberTRG");
1200 G4Material* medHV = geometry::Materials::get(
"CDCHVCable");
1202 m_VisAttributes.push_back(
new G4VisAttributes(
true, G4Colour(0., 1., 0.)));
1203 const int nCover = content.getNumberNodes(
"Covers/Cover");
1204 for (
int iCover = 0; iCover < nCover; ++iCover) {
1205 GearDir coverContent(content);
1206 coverContent.
append((format(
"/Covers/Cover[%1%]/") % (iCover + 1)).str());
1207 const string scoverID = coverContent.
getString(
"@id");
1208 const int coverID = atoi(scoverID.c_str());
1209 const string coverName = coverContent.
getString(
"Name");
1210 const double coverInnerR1 = coverContent.
getLength(
"InnerR1");
1211 const double coverInnerR2 = coverContent.
getLength(
"InnerR2");
1212 const double coverOuterR1 = coverContent.
getLength(
"OuterR1");
1213 const double coverOuterR2 = coverContent.
getLength(
"OuterR2");
1214 const double coverThick = coverContent.
getLength(
"Thickness");
1215 const double coverPosZ = coverContent.
getLength(
"PosZ");
1217 const double rmin1 = coverInnerR1;
1218 const double rmax1 = coverOuterR1;
1219 const double rmin2 = coverInnerR2;
1220 const double rmax2 = coverOuterR2;
1231 if (coverID == 7 || coverID == 10) {
1232 createCone(rmin1, rmax1, rmin2, rmax2, coverThick, coverPosZ, coverID, medAluminum, coverName);
1234 createTube(rmin1, rmax1, coverThick, coverPosZ, coverID, medAluminum, coverName);
1237 if (coverID > 22 && coverID < 29)
1238 createTube(rmin1, rmax1, coverThick, coverPosZ, coverID, medCopper, coverName);
1239 if (coverID > 28 && coverID < 35)
1240 createTorus(rmin1, rmax1, coverThick, coverPosZ, coverID, medCopper, coverName);
1241 if (coverID > 34 && coverID < 41)
1242 createTorus(rmin1, rmax1, coverThick, coverPosZ, coverID, medH2O, coverName);
1243 if (coverID == 45 || coverID == 46)
1244 createTube(rmin1, rmax1, coverThick, coverPosZ, coverID, medLV, coverName);
1245 if (coverID == 47 || coverID == 48)
1246 createTube(rmin1, rmax1, coverThick, coverPosZ, coverID, medFiber, coverName);
1247 if (coverID == 49 || coverID == 50)
1248 createTube(rmin1, rmax1, coverThick, coverPosZ, coverID, medCAT7, coverName);
1249 if (coverID == 51 || coverID == 52)
1250 createTube(rmin1, rmax1, coverThick, coverPosZ, coverID, medTRG, coverName);
1252 createTube(rmin1, rmax1, coverThick, coverPosZ, coverID, medHV, coverName);
1255 const int nCover2 = content.getNumberNodes(
"Covers/Cover2");
1256 for (
int iCover2 = 0; iCover2 < nCover2; ++iCover2) {
1257 GearDir cover2Content(content);
1258 cover2Content.
append((format(
"/Cover2s/Cover2[%1%]/") % (iCover2 + 1)).str());
1259 const string scover2ID = cover2Content.
getString(
"@id");
1260 const int cover2ID = atoi(scover2ID.c_str());
1261 const string cover2Name = cover2Content.
getString(
"Name");
1262 const double cover2InnerR = cover2Content.
getLength(
"InnerR");
1263 const double cover2OuterR = cover2Content.
getLength(
"OuterR");
1264 const double cover2StartPhi = cover2Content.
getLength(
"StartPhi");
1265 const double cover2DeltaPhi = cover2Content.
getLength(
"DeltaPhi");
1266 const double cover2Thick = cover2Content.
getLength(
"Thickness");
1267 const double cover2PosZ = cover2Content.
getLength(
"PosZ");
1270 createTube2(cover2InnerR, cover2OuterR, cover2StartPhi, cover2DeltaPhi, cover2Thick, cover2PosZ, cover2ID, medHV, cover2Name);
1271 if (cover2ID > 10 && cover2ID < 14)
1272 createTube2(cover2InnerR, cover2OuterR, cover2StartPhi, cover2DeltaPhi, cover2Thick, cover2PosZ, cover2ID, medFiber, cover2Name);
1273 if (cover2ID > 13 && cover2ID < 23)
1274 createTube2(cover2InnerR, cover2OuterR, cover2StartPhi, cover2DeltaPhi, cover2Thick, cover2PosZ, cover2ID, medCAT7, cover2Name);
1275 if (cover2ID > 22 && cover2ID < 29)
1276 createTube2(cover2InnerR, cover2OuterR, cover2StartPhi, cover2DeltaPhi, cover2Thick, cover2PosZ, cover2ID, medTRG, cover2Name);
1279 const int nRibs = content.getNumberNodes(
"Covers/Rib");
1280 for (
int iRib = 0; iRib < nRibs; ++iRib) {
1282 ribContent.
append((format(
"/Covers/Rib[%1%]/") % (iRib + 1)).str());
1283 const string sribID = ribContent.
getString(
"@id");
1284 const int ribID = atoi(sribID.c_str());
1286 const double length = ribContent.
getLength(
"Length");
1287 const double width = ribContent.
getLength(
"Width");
1288 const double thick = ribContent.
getLength(
"Thickness");
1289 const double rotX = ribContent.
getLength(
"RotX");
1290 const double rotY = ribContent.
getLength(
"RotY");
1291 const double rotZ = ribContent.
getLength(
"RotZ");
1292 const double cX = ribContent.
getLength(
"PosX");
1293 const double cY = ribContent.
getLength(
"PosY");
1294 const double cZ = ribContent.
getLength(
"PosZ");
1295 const int offset = atoi((ribContent.
getString(
"Offset")).c_str());
1296 const int number = atoi((ribContent.
getString(
"NDiv")).c_str());
1298 const string solidName =
"solidRib" + to_string(ribID);
1299 const string logicalName =
"logicalRib" + to_string(ribID);
1300 G4Box* boxShape =
new G4Box(solidName, 0.5 * length * CLHEP::cm,
1301 0.5 * width * CLHEP::cm,
1302 0.5 * thick * CLHEP::cm);
1303 const double rmax = 0.5 * length;
1304 const double rmin = max((rmax - thick), 0.);
1305 G4Tubs* tubeShape =
new G4Tubs(solidName,
1308 0.5 * width * CLHEP::cm,
1315 G4LogicalVolume* logicalV =
new G4LogicalVolume(boxShape, medAluminum, logicalName, 0, 0, 0);
1316 if (ribID > 39 && ribID < 78)
1317 logicalV =
new G4LogicalVolume(boxShape, medCopper, logicalName, 0, 0, 0);
1318 if ((ribID > 77 && ribID < 94) || (ribID > 131 && ribID < 146))
1319 logicalV =
new G4LogicalVolume(boxShape, medNEMA_G10_Plate, logicalName, 0, 0, 0);
1320 if (ribID > 93 && ribID < 110)
1321 logicalV =
new G4LogicalVolume(tubeShape, medCopper, logicalName, 0, 0, 0);
1322 if (ribID > 109 && ribID < 126)
1323 logicalV =
new G4LogicalVolume(tubeShape, medH2O, logicalName, 0, 0, 0);
1324 if (ribID > 127 && ribID < 132)
1325 logicalV =
new G4LogicalVolume(boxShape, medHV, logicalName, 0, 0, 0);
1333 logicalV->SetVisAttributes(m_VisAttributes.back());
1335 const double phi = 360.0 / number;
1337 G4RotationMatrix rot = G4RotationMatrix();
1340 if (ribID > 93 && ribID < 126) dz = 0;
1341 G4ThreeVector arm(cX * CLHEP::cm, cY * CLHEP::cm, cZ * CLHEP::cm - dz * CLHEP::cm / 2.0);
1347 rot.rotateZ(0.5 * phi * CLHEP::deg);
1348 arm.rotateZ(0.5 * phi * CLHEP::deg);
1350 for (
int i = 0; i < number; ++i) {
1351 const string physicalName =
"physicalRib_" + to_string(ribID) +
" " + to_string(i);
1352 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
1353 physicalName.c_str(), logical_cdc,
false, ribID);
1354 rot.rotateZ(phi * CLHEP::deg);
1355 arm.rotateZ(phi * CLHEP::deg);
1360 const int nRib2s = content.getNumberNodes(
"Covers/Rib2");
1361 for (
int iRib2 = 0; iRib2 < nRib2s; ++iRib2) {
1363 rib2Content.
append((format(
"/Covers/Rib2[%1%]/") % (iRib2 + 1)).str());
1364 const string srib2ID = rib2Content.
getString(
"@id");
1365 const int rib2ID = atoi(srib2ID.c_str());
1367 const double length = rib2Content.
getLength(
"Length");
1368 const double width = rib2Content.
getLength(
"Width");
1369 const double thick = rib2Content.
getLength(
"Thickness");
1370 const double width2 = rib2Content.
getLength(
"Width2");
1371 const double thick2 = rib2Content.
getLength(
"Thickness2");
1372 const double rotX = rib2Content.
getLength(
"RotX");
1373 const double rotY = rib2Content.
getLength(
"RotY");
1374 const double rotZ = rib2Content.
getLength(
"RotZ");
1375 const double cX = rib2Content.
getLength(
"PosX");
1376 const double cY = rib2Content.
getLength(
"PosY");
1377 const double cZ = rib2Content.
getLength(
"PosZ");
1378 const int number = atoi((rib2Content.
getString(
"NDiv")).c_str());
1380 const string solidName =
"solidRib2" + to_string(rib2ID);
1381 const string logicalName =
"logicalRib2" + to_string(rib2ID);
1382 G4Trd* trdShape =
new G4Trd(solidName,
1383 0.5 * thick * CLHEP::cm,
1384 0.5 * thick2 * CLHEP::cm,
1385 0.5 * width * CLHEP::cm,
1386 0.5 * width2 * CLHEP::cm,
1387 0.5 * length * CLHEP::cm);
1389 G4LogicalVolume* logicalV =
new G4LogicalVolume(trdShape, medAluminum, logicalName, 0, 0, 0);
1391 logicalV =
new G4LogicalVolume(trdShape, medCopper, logicalName, 0, 0, 0);
1393 logicalV->SetVisAttributes(m_VisAttributes.back());
1395 const double phi = 360.0 / number;
1397 G4RotationMatrix rot = G4RotationMatrix();
1398 G4ThreeVector arm(cX * CLHEP::cm, cY * CLHEP::cm, cZ * CLHEP::cm - thick * CLHEP::cm / 2.0);
1403 for (
int i = 0; i < number; ++i) {
1404 const string physicalName =
"physicalRib2_" + to_string(rib2ID) +
" " + to_string(i);
1405 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
1406 physicalName.c_str(), logical_cdc,
false, rib2ID);
1407 rot.rotateZ(phi * CLHEP::deg);
1408 arm.rotateZ(phi * CLHEP::deg);
1413 const int nRib3s = content.getNumberNodes(
"Covers/Rib3");
1414 for (
int iRib3 = 0; iRib3 < nRib3s; ++iRib3) {
1416 rib3Content.
append((format(
"/Covers/Rib3[%1%]/") % (iRib3 + 1)).str());
1417 const string srib3ID = rib3Content.
getString(
"@id");
1418 const int rib3ID = atoi(srib3ID.c_str());
1420 const double length = rib3Content.
getLength(
"Length");
1421 const double width = rib3Content.
getLength(
"Width");
1422 const double thick = rib3Content.
getLength(
"Thickness");
1423 const double r = rib3Content.
getLength(
"HoleR");
1424 const double cX = rib3Content.
getLength(
"PosX");
1425 const double cY = rib3Content.
getLength(
"PosY");
1426 const double cZ = rib3Content.
getLength(
"PosZ");
1427 const double hX = rib3Content.
getLength(
"HoleX");
1428 const double hY = rib3Content.
getLength(
"HoleY");
1429 const double hZ = rib3Content.
getLength(
"HoleZ");
1430 const int offset = atoi((rib3Content.
getString(
"Offset")).c_str());
1431 const int number = atoi((rib3Content.
getString(
"NDiv")).c_str());
1433 const string logicalName =
"logicalRib3" + to_string(rib3ID);
1434 G4VSolid* boxShape =
new G4Box(
"Block",
1435 0.5 * length * CLHEP::cm,
1436 0.5 * width * CLHEP::cm,
1437 0.5 * thick * CLHEP::cm);
1438 G4VSolid* tubeShape =
new G4Tubs(
"Hole",
1444 G4RotationMatrix rotsub = G4RotationMatrix();
1445 G4ThreeVector trnsub(cX * CLHEP::cm - hX * CLHEP::cm, cY * CLHEP::cm - hY * CLHEP::cm,
1446 cZ * CLHEP::cm - hZ * CLHEP::cm + 0.5 * thick * CLHEP::cm);
1447 G4VSolid* coolingBlock =
new G4SubtractionSolid(
"Block-Hole",
1450 G4Transform3D(rotsub,
1453 G4LogicalVolume* logicalV =
new G4LogicalVolume(coolingBlock, medCopper, logicalName, 0, 0, 0);
1455 logicalV->SetVisAttributes(m_VisAttributes.back());
1457 const double phi = 360.0 / number;
1459 G4RotationMatrix rot = G4RotationMatrix();
1460 G4ThreeVector arm(cX * CLHEP::cm, cY * CLHEP::cm, cZ * CLHEP::cm - thick * CLHEP::cm / 2.0);
1463 rot.rotateZ(0.5 * phi * CLHEP::deg);
1464 arm.rotateZ(0.5 * phi * CLHEP::deg);
1466 for (
int i = 0; i < number; ++i) {
1467 const string physicalName =
"physicalRib3_" + to_string(rib3ID) +
" " + to_string(i);
1468 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
1469 physicalName.c_str(), logical_cdc,
false, rib3ID);
1470 rot.rotateZ(phi * CLHEP::deg);
1471 arm.rotateZ(phi * CLHEP::deg);
1476 const int nRib4s = content.getNumberNodes(
"Covers/Rib4");
1477 for (
int iRib4 = 0; iRib4 < nRib4s; ++iRib4) {
1479 rib4Content.
append((format(
"/Covers/Rib4[%1%]/") % (iRib4 + 1)).str());
1480 const string srib4ID = rib4Content.
getString(
"@id");
1481 const int rib4ID = atoi(srib4ID.c_str());
1483 const double length = rib4Content.
getLength(
"Length");
1484 const double width = rib4Content.
getLength(
"Width");
1485 const double thick = rib4Content.
getLength(
"Thickness");
1486 const double length2 = rib4Content.
getLength(
"Length2");
1487 const double width2 = rib4Content.
getLength(
"Width2");
1488 const double thick2 = rib4Content.
getLength(
"Thickness2");
1489 const double cX = rib4Content.
getLength(
"PosX");
1490 const double cY = rib4Content.
getLength(
"PosY");
1491 const double cZ = rib4Content.
getLength(
"PosZ");
1492 const double hX = rib4Content.
getLength(
"HoleX");
1493 const double hY = rib4Content.
getLength(
"HoleY");
1494 const double hZ = rib4Content.
getLength(
"HoleZ");
1495 const int offset = atoi((rib4Content.
getString(
"Offset")).c_str());
1496 const int number = atoi((rib4Content.
getString(
"NDiv")).c_str());
1498 const string logicalName =
"logicalRib4" + to_string(rib4ID);
1499 G4VSolid* baseShape =
new G4Box(
"Base",
1500 0.5 * length * CLHEP::cm,
1501 0.5 * width * CLHEP::cm,
1502 0.5 * thick * CLHEP::cm);
1503 G4VSolid* sqShape =
new G4Box(
"Sq",
1504 0.5 * length2 * CLHEP::cm,
1505 0.5 * width2 * CLHEP::cm,
1506 0.5 * thick2 * CLHEP::cm);
1507 G4RotationMatrix rotsub = G4RotationMatrix();
1508 double dzc = (hZ - thick2 / 2.) - (cZ - thick / 2.);
1509 G4ThreeVector trnsub(hX * CLHEP::cm - cX * CLHEP::cm,
1510 hY * CLHEP::cm - cY * CLHEP::cm,
1512 G4VSolid* sqHoleBase =
new G4SubtractionSolid(
"Base-Sq",
1515 G4Transform3D(rotsub,
1519 G4LogicalVolume* logicalV =
new G4LogicalVolume(sqHoleBase, medCopper, logicalName, 0, 0, 0);
1521 logicalV =
new G4LogicalVolume(sqHoleBase, medNEMA_G10_Plate, logicalName, 0, 0, 0);
1523 logicalV->SetVisAttributes(m_VisAttributes.back());
1525 const double phi = 360.0 / number;
1527 G4RotationMatrix rot = G4RotationMatrix();
1528 G4ThreeVector arm(cX * CLHEP::cm, cY * CLHEP::cm, cZ * CLHEP::cm - thick * CLHEP::cm / 2.0);
1531 rot.rotateZ(0.5 * phi * CLHEP::deg);
1532 arm.rotateZ(0.5 * phi * CLHEP::deg);
1534 for (
int i = 0; i < number; ++i) {
1535 const string physicalName =
"physicalRib4_" + to_string(rib4ID) +
" " + to_string(i);
1536 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
1537 physicalName.c_str(), logical_cdc,
false, rib4ID);
1538 rot.rotateZ(phi * CLHEP::deg);
1539 arm.rotateZ(phi * CLHEP::deg);
1544 const int nRib5s = content.getNumberNodes(
"Covers/Rib5");
1545 for (
int iRib5 = 0; iRib5 < nRib5s; ++iRib5) {
1547 rib5Content.
append((format(
"/Covers/Rib5[%1%]/") % (iRib5 + 1)).str());
1548 const string srib5ID = rib5Content.
getString(
"@id");
1549 const int rib5ID = atoi(srib5ID.c_str());
1551 const double dr = rib5Content.
getLength(
"DeltaR");
1552 const double dz = rib5Content.
getLength(
"DeltaZ");
1553 const double width = rib5Content.
getLength(
"Width");
1554 const double thick = rib5Content.
getLength(
"Thickness");
1555 const double rin = rib5Content.
getLength(
"Rin");
1556 const double rotX = rib5Content.
getLength(
"RotX");
1557 const double rotY = rib5Content.
getLength(
"RotY");
1558 const double rotZ = rib5Content.
getLength(
"RotZ");
1559 const double cX = rib5Content.
getLength(
"PosX");
1560 const double cY = rib5Content.
getLength(
"PosY");
1561 const double cZ = rib5Content.
getLength(
"PosZ");
1562 const int offset = atoi((rib5Content.
getString(
"Offset")).c_str());
1563 const int number = atoi((rib5Content.
getString(
"NDiv")).c_str());
1565 const string solidName =
"solidRib5" + to_string(rib5ID);
1566 const string logicalName =
"logicalRib5" + to_string(rib5ID);
1567 const double rmax = rin + thick;
1568 const double rmin = rin;
1569 const double dphi = 2. * atan2(dz, dr);
1570 const double ddphi = thick * tan(dphi) / rin;
1571 const double ddphi2 = width / 2. * width / 2. / (cX + dr) / rin;
1572 const double cphi = dphi - ddphi - ddphi2;
1573 G4Tubs* tubeShape =
new G4Tubs(solidName,
1576 0.5 * width * CLHEP::cm,
1580 G4LogicalVolume* logicalV =
new G4LogicalVolume(tubeShape, medAluminum, logicalName, 0, 0, 0);
1582 logicalV->SetVisAttributes(m_VisAttributes.back());
1584 const double phi = 360.0 / number;
1586 G4RotationMatrix rot = G4RotationMatrix();
1589 G4ThreeVector arm(cX * CLHEP::cm, cY * CLHEP::cm, cZ * CLHEP::cm - rin * CLHEP::cm - thick * CLHEP::cm);
1595 rot.rotateZ(0.5 * phi * CLHEP::deg);
1596 arm.rotateZ(0.5 * phi * CLHEP::deg);
1598 for (
int i = 0; i < number; ++i) {
1599 const string physicalName =
"physicalRib5_" + to_string(rib5ID) +
" " + to_string(i);
1600 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
1601 physicalName.c_str(), logical_cdc,
false, rib5ID);
1602 rot.rotateZ(phi * CLHEP::deg);
1603 arm.rotateZ(phi * CLHEP::deg);
1612 G4Material* medAl = geometry::Materials::get(
"Al");
1614 G4double density = 1.000 * CLHEP::g / CLHEP::cm3;
1615 G4double a = 1.01 * CLHEP::g / CLHEP::mole;
1616 G4Element* elH =
new G4Element(
"Hydrogen",
"H", 1., a);
1617 a = 16.00 * CLHEP::g / CLHEP::mole;
1618 G4Element* elO =
new G4Element(
"Oxygen",
"O", 8., a);
1619 G4Material* medH2O =
new G4Material(
"water", density, 2);
1620 medH2O->AddElement(elH, 2);
1621 medH2O->AddElement(elO, 1);
1622 G4Material* medCu = geometry::Materials::get(
"Cu");
1623 G4Material* medLV = geometry::Materials::get(
"CDCLVCable");
1624 G4Material* medFiber = geometry::Materials::get(
"CDCOpticalFiber");
1625 G4Material* medCAT7 = geometry::Materials::get(
"CDCCAT7");
1626 G4Material* medTRG = geometry::Materials::get(
"CDCOpticalFiberTRG");
1627 G4Material* medHV = geometry::Materials::get(
"CDCHVCable");
1629 m_VisAttributes.push_back(
new G4VisAttributes(
true, G4Colour(0., 1., 0.)));
1630 for (
const auto& cover : geom.getCovers()) {
1631 const int coverID = cover.getId();
1632 const string coverName =
"cover" + to_string(coverID);
1633 const double rmin1 = cover.getRmin1();
1634 const double rmin2 = cover.getRmin2();
1635 const double rmax1 = cover.getRmax1();
1636 const double rmax2 = cover.getRmax2();
1637 const double thick = cover.getThick();
1638 const double posZ = cover.getZ();
1647 if (coverID == 7 || coverID == 10) {
1648 createCone(rmin1, rmax1, rmin2, rmax2, thick, posZ, coverID, medAl, coverName);
1650 createTube(rmin1, rmax1, thick, posZ, coverID, medAl, coverName);
1653 if (coverID > 22 && coverID < 29)
1654 createTube(rmin1, rmax1, thick, posZ, coverID, medCu, coverName);
1655 if (coverID > 28 && coverID < 35)
1656 createTorus(rmin1, rmax1, thick, posZ, coverID, medCu, coverName);
1657 if (coverID > 34 && coverID < 41)
1658 createTorus(rmin1, rmax1, thick, posZ, coverID, medH2O, coverName);
1659 if (coverID == 45 || coverID == 46)
1660 createTube(rmin1, rmax1, thick, posZ, coverID, medLV, coverName);
1661 if (coverID == 47 || coverID == 48)
1662 createTube(rmin1, rmax1, thick, posZ, coverID, medFiber, coverName);
1663 if (coverID == 49 || coverID == 50)
1664 createTube(rmin1, rmax1, thick, posZ, coverID, medCAT7, coverName);
1665 if (coverID == 51 || coverID == 52)
1666 createTube(rmin1, rmax1, thick, posZ, coverID, medTRG, coverName);
1668 createTube(rmin1, rmax1, thick, posZ, coverID, medHV, coverName);
1674 G4Material* medHV = geometry::Materials::get(
"CDCHVCable");
1675 G4Material* medFiber = geometry::Materials::get(
"CDCOpticalFiber");
1676 G4Material* medCAT7 = geometry::Materials::get(
"CDCCAT7");
1677 G4Material* medTRG = geometry::Materials::get(
"CDCOpticalFiberTRG");
1679 m_VisAttributes.push_back(
new G4VisAttributes(
true, G4Colour(0., 1., 0.)));
1680 for (
const auto& cover2 : geom.getCover2s()) {
1681 const int cover2ID = cover2.getId();
1682 const string cover2Name =
"cover2" + to_string(cover2ID);
1683 const double rmin = cover2.getRmin();
1684 const double rmax = cover2.getRmax();
1685 const double phis = cover2.getPhis();
1686 const double dphi = cover2.getDphi();
1687 const double thick = cover2.getThick();
1688 const double posZ = cover2.getZ();
1691 createTube2(rmin, rmax, phis, dphi, thick, posZ, cover2ID, medHV, cover2Name);
1692 if (cover2ID > 10 && cover2ID < 14)
1693 createTube2(rmin, rmax, phis, dphi, thick, posZ, cover2ID, medFiber, cover2Name);
1694 if (cover2ID > 13 && cover2ID < 23)
1695 createTube2(rmin, rmax, phis, dphi, thick, posZ, cover2ID, medCAT7, cover2Name);
1696 if (cover2ID > 22 && cover2ID < 29)
1697 createTube2(rmin, rmax, phis, dphi, thick, posZ, cover2ID, medTRG, cover2Name);
1701 void GeoCDCCreator::createCone(
const double rmin1,
const double rmax1,
1702 const double rmin2,
const double rmax2,
1703 const double thick,
const double posZ,
1704 const int id, G4Material* med,
1707 const string solidName =
"solid" + name;
1708 const string logicalName =
"logical" + name;
1709 const string physicalName =
"physical" + name;
1710 G4Cons* coverConeShape =
new G4Cons(solidName.c_str(), rmin1 * CLHEP::cm, rmax1 * CLHEP::cm,
1711 rmin2 * CLHEP::cm, rmax2 * CLHEP::cm, thick * CLHEP::cm / 2.0, 0.*CLHEP::deg, 360.*CLHEP::deg);
1712 G4LogicalVolume* coverCone =
new G4LogicalVolume(coverConeShape, med,
1713 logicalName.c_str(), 0, 0, 0);
1714 coverCone->SetVisAttributes(m_VisAttributes.back());
1715 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, posZ * CLHEP::cm - thick * CLHEP::cm / 2.0), coverCone,
1716 physicalName.c_str(), logical_cdc,
false,
id);
1720 void GeoCDCCreator::createTube(
const double rmin,
const double rmax,
1721 const double thick,
const double posZ,
1722 const int id, G4Material* med,
1725 const string solidName =
"solid" + name;
1726 const string logicalName =
"logical" + name;
1727 const string physicalName =
"physical" + name;
1728 G4Tubs* solidV =
new G4Tubs(solidName.c_str(),
1731 thick * CLHEP::cm / 2.0,
1734 G4LogicalVolume* logicalV =
new G4LogicalVolume(solidV, med,
1735 logicalName.c_str(), 0, 0, 0);
1736 logicalV->SetVisAttributes(m_VisAttributes.back());
1737 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, posZ * CLHEP::cm - thick * CLHEP::cm / 2.0), logicalV,
1738 physicalName.c_str(), logical_cdc,
false,
id);
1742 void GeoCDCCreator::createBox(
const double length,
const double height,
1743 const double thick,
const double x,
1744 const double y,
const double z,
1745 const int id, G4Material* med,
1748 const string solidName = (format(
"solid%1%%2%") % name % id).str();
1749 const string logicalName = (format(
"logical%1%%2%") % name % id).str();
1750 const string physicalName = (format(
"physical%1%%2%") % name % id).str();
1751 G4Box* boxShape =
new G4Box(solidName.c_str(), 0.5 * length * CLHEP::cm,
1752 0.5 * height * CLHEP::cm,
1753 0.5 * thick * CLHEP::cm);
1754 G4LogicalVolume* logicalV =
new G4LogicalVolume(boxShape, med,
1755 logicalName.c_str(), 0, 0, 0);
1756 logicalV->SetVisAttributes(m_VisAttributes.back());
1757 new G4PVPlacement(0, G4ThreeVector(x * CLHEP::cm, y * CLHEP::cm, z * CLHEP::cm - thick * CLHEP::cm / 2.0), logicalV,
1758 physicalName.c_str(), logical_cdc,
false,
id);
1762 void GeoCDCCreator::createTorus(
const double rmin1,
const double rmax1,
1763 const double thick,
const double posZ,
1764 const int id, G4Material* med,
1767 const string solidName =
"solid" + name;
1768 const string logicalName =
"logical" + name;
1769 const string physicalName =
"physical" + name;
1770 const double rtor = (rmax1 + rmin1) / 2.;
1771 const double rmax = rmax1 - rtor;
1772 const double rmin = max((rmax - thick), 0.);
1774 G4Torus* solidV =
new G4Torus(solidName.c_str(),
1780 G4LogicalVolume* logicalV =
new G4LogicalVolume(solidV, med,
1781 logicalName.c_str(), 0, 0, 0);
1782 logicalV->SetVisAttributes(m_VisAttributes.back());
1783 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, posZ * CLHEP::cm), logicalV,
1784 physicalName.c_str(), logical_cdc,
false,
id);
1788 void GeoCDCCreator::createTube2(
const double rmin,
const double rmax,
1789 const double phis,
const double phie,
1790 const double thick,
const double posZ,
1791 const int id, G4Material* med,
1794 const string solidName =
"solid" + name;
1795 const string logicalName =
"logical" + name;
1796 const string physicalName =
"physical" + name;
1797 G4Tubs* solidV =
new G4Tubs(solidName.c_str(),
1800 thick * CLHEP::cm / 2.0,
1803 G4LogicalVolume* logicalV =
new G4LogicalVolume(solidV, med,
1804 logicalName.c_str(), 0, 0, 0);
1805 logicalV->SetVisAttributes(m_VisAttributes.back());
1806 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, posZ * CLHEP::cm - thick * CLHEP::cm / 2.0), logicalV,
1807 physicalName.c_str(), logical_cdc,
false,
id);
1811 void GeoCDCCreator::createMapper(G4LogicalVolume& topVolume)
1816 const double xc = 0.5 * (-0.0002769 + 0.0370499) * CLHEP::cm;
1817 const double yc = 0.5 * (-0.0615404 + -0.108948) * CLHEP::cm;
1818 const double zc = 0.5 * (-35.3 + 48.5) * CLHEP::cm;
1823 const double plateWidth = 13.8 * CLHEP::cm;
1824 const double plateThick = 1.2 * CLHEP::cm;
1825 const double plateLength = 83.8 * CLHEP::cm;
1831 const double endPlateRmin = 4.0 * CLHEP::cm;
1832 const double endPlateRmax = 15.5 * CLHEP::cm;
1833 const double bwdEndPlateThick = 1.7 * CLHEP::cm;
1834 const double fwdEndPlateThick = 2.0 * CLHEP::cm;
1836 G4Material* medAluminum = geometry::Materials::get(
"Al");
1838 string name =
"Plate";
1840 G4Box* plateShape =
new G4Box(
"solid" + name, .5 * plateWidth, .5 * plateThick, .5 * plateLength);
1841 G4LogicalVolume* logical0 =
new G4LogicalVolume(plateShape, medAluminum,
"logical" + name, 0, 0, 0);
1842 logical0->SetVisAttributes(m_VisAttributes.back());
1844 const double x = xc + 0.5 * plateWidth;
1846 const double y = yc + endPlateRmin + 0.1 * CLHEP::cm;
1848 G4ThreeVector xyz(x, y, zc);
1849 G4RotationMatrix rotM3 = G4RotationMatrix();
1852 new G4PVPlacement(G4Transform3D(rotM3, xyz), logical0,
"physical" + name, &topVolume,
false, pID);
1854 const double alf = 120. * CLHEP::deg;
1857 new G4PVPlacement(G4Transform3D(rotM3, xyz), logical0,
"physical" + name, &topVolume,
false, pID + 1);
1861 new G4PVPlacement(G4Transform3D(rotM3, xyz), logical0,
"physical" + name, &topVolume,
false, pID + 2);
1865 name =
"BwdEndPlate";
1866 G4Tubs* BwdEndPlateShape =
new G4Tubs(
"solid" + name, endPlateRmin, endPlateRmax, 0.5 * bwdEndPlateThick, 0., 360.*CLHEP::deg);
1867 G4LogicalVolume* logical1 =
new G4LogicalVolume(BwdEndPlateShape, medAluminum,
"logical" + name, 0, 0, 0);
1868 logical1->SetVisAttributes(m_VisAttributes.back());
1870 double z = -35.3 * CLHEP::cm - 0.5 * bwdEndPlateThick;
1872 new G4PVPlacement(0, G4ThreeVector(xc, yc, z), logical1,
"physical" + name, &topVolume,
false, pID);
1877 name =
"FwdEndPlate";
1878 G4Tubs* FwdEndPlateShape =
new G4Tubs(
"solid" + name, endPlateRmin, endPlateRmax, 0.5 * fwdEndPlateThick, 0., 360.*CLHEP::deg);
1879 G4LogicalVolume* logical2 =
new G4LogicalVolume(FwdEndPlateShape, medAluminum,
"logical" + name, 0, 0, 0);
1880 logical2->SetVisAttributes(m_VisAttributes.back());
1881 z = 48.5 * CLHEP::cm + 0.5 * fwdEndPlateThick;
1882 new G4PVPlacement(0, G4ThreeVector(xc, yc, z), logical2,
"physical" + name, &topVolume,
false, pID);