9 #include <cdc/geometry/GeoCDCCreator.h>
10 #include <cdc/geometry/CDCGeometryPar.h>
11 #include <cdc/geometry/CDCGeoControlPar.h>
12 #include <cdc/simulation/CDCSimControlPar.h>
13 #include <cdc/simulation/CDCSensitiveDetector.h>
14 #include <simulation/background/BkgSensitiveDetector.h>
16 #include <geometry/CreatorFactory.h>
17 #include <geometry/Materials.h>
20 #include <boost/format.hpp>
22 #include <G4Material.hh>
23 #include <G4ProductionCuts.hh>
28 #include <G4SubtractionSolid.hh>
29 #include <G4Region.hh>
30 #include <G4VSolid.hh>
32 #include <G4Polycone.hh>
34 #include <G4Colour.hh>
35 #include <G4LogicalVolume.hh>
36 #include <G4PVPlacement.hh>
37 #include <G4Transform3D.hh>
38 #include <G4VisAttributes.hh>
39 #include <G4RotationMatrix.hh>
40 #include <G4UserLimits.hh>
44 using namespace boost;
52 using namespace geometry;
66 GeoCDCCreator::GeoCDCCreator()
69 CDCSimControlPar::getInstance();
70 CDCGeoControlPar::getInstance();
74 m_VisAttributes.clear();
75 m_VisAttributes.push_back(
new G4VisAttributes(
false));
80 GeoCDCCreator::~GeoCDCCreator()
83 if (m_bkgsensitive)
delete m_bkgsensitive;
85 delete sensitiveDetector;
86 for (G4VisAttributes* visAttr : m_VisAttributes)
delete visAttr;
87 m_VisAttributes.clear();
88 for (G4UserLimits* userLimits : m_userLimits)
delete userLimits;
95 m_sensitive =
new CDCSensitiveDetector(
"CDCSensitiveDetector", (2 * 24)* CLHEP::eV, 10 * CLHEP::MeV);
97 const G4double realTemperture = (273.15 + 23.) * CLHEP::kelvin;
98 G4Material* medHelium = geometry::Materials::get(
"CDCHeGas");
99 G4Material* medEthane = geometry::Materials::get(
"CDCEthaneGas");
100 G4Material* medAluminum = geometry::Materials::get(
"Al");
101 G4Material* medTungsten = geometry::Materials::get(
"W");
102 G4Material* medCFRP = geometry::Materials::get(
"CFRP");
103 G4Material* medNEMA_G10_Plate = geometry::Materials::get(
"NEMA_G10_Plate");
104 G4Material* medGlue = geometry::Materials::get(
"CDCGlue");
105 G4Material* medAir = geometry::Materials::get(
"Air");
107 G4double h2odensity = 1.000 * CLHEP::g / CLHEP::cm3;
108 G4double a = 1.01 * CLHEP::g / CLHEP::mole;
109 G4Element* elH =
new G4Element(
"Hydrogen",
"H", 1., a);
110 a = 16.00 * CLHEP::g / CLHEP::mole;
111 G4Element* elO =
new G4Element(
"Oxygen",
"O", 8., a);
112 G4Material* medH2O =
new G4Material(
"Water", h2odensity, 2);
113 medH2O->AddElement(elH, 2);
114 medH2O->AddElement(elO, 1);
115 G4Material* medCopper = geometry::Materials::get(
"Cu");
116 G4Material* medHV = geometry::Materials::get(
"CDCHVCable");
126 const double num_senseWire =
static_cast<double>(geo.
getNSenseWires());
127 const double num_fieldWire =
static_cast<double>(geo.
getNFieldWires());
128 double totalCS = M_PI * (rmin_outerWall * rmin_outerWall - rmax_innerWall * rmax_innerWall);
131 double senseCS = M_PI * (diameter_senseWire / 2) * (diameter_senseWire / 2) * num_senseWire;
134 double fieldCS = M_PI * (diameter_fieldWire / 2) * (diameter_fieldWire / 2) * num_fieldWire;
137 const double denHelium = medHelium->GetDensity() / 2.0;
138 const double denEthane = medEthane->GetDensity() / 2.0;
139 const double denAluminum = medAluminum->GetDensity() * (fieldCS / totalCS);
140 const double denTungsten = medTungsten->GetDensity() * (senseCS / totalCS);
141 const double density = denHelium + denEthane + denAluminum + denTungsten;
142 G4Material* cdcMed =
new G4Material(
"CDCGasWire", density, 4, kStateGas, realTemperture);
143 cdcMed->AddMaterial(medHelium, denHelium / density);
144 cdcMed->AddMaterial(medEthane, denEthane / density);
145 cdcMed->AddMaterial(medTungsten, denTungsten / density);
146 cdcMed->AddMaterial(medAluminum, denAluminum / density);
148 G4Material* cdcMedGas = cdcMed;
156 const double density2 = denHelium + denEthane;
157 cdcMedGas =
new G4Material(
"CDCRealGas", density2, 2, kStateGas, realTemperture);
158 cdcMedGas->AddMaterial(medHelium, denHelium / density2);
159 cdcMedGas->AddMaterial(medEthane, denEthane / density2);
163 G4cout << *(G4Material::GetMaterialTable());
167 const auto& motherRmin = mother.getRmin();
168 const auto& motherRmax = mother.getRmax();
169 const auto& motherZ = mother.getZ();
170 G4Polycone* solid_cdc =
171 new G4Polycone(
"solidCDC", 0 * CLHEP::deg, 360.* CLHEP::deg,
172 mother.getNNodes(), motherZ.data(),
173 motherRmin.data(), motherRmax.data());
174 logical_cdc =
new G4LogicalVolume(solid_cdc, medAir,
"logicalCDC", 0, 0, 0);
175 physical_cdc =
new G4PVPlacement(0, G4ThreeVector(geo.
getGlobalOffsetX() * CLHEP::cm,
178 "physicalCDC", &topVolume,
false, 0);
181 G4Region* aRegion =
new G4Region(
"CDCEnvelope");
182 logical_cdc->SetRegion(aRegion);
183 aRegion->AddRootLogicalVolume(logical_cdc);
185 m_VisAttributes.push_back(
new G4VisAttributes(
true, G4Colour(0., 1., 0.)));
187 const int iOuterWall = wall.getId();
188 const string wallName = wall.getName();
189 const double wallRmin = wall.getRmin();
190 const double wallRmax = wall.getRmax();
191 const double wallZfwd = wall.getZfwd();
192 const double wallZbwd = wall.getZbwd();
193 const double length = (wallZfwd - wallZbwd) / 2.0;
196 G4Material* medWall = medAir;
197 if (strstr((wallName).c_str(),
"MiddleWall") !=
nullptr) {
201 medWall = medAluminum;
203 G4Tubs* outerWallTubeShape =
new G4Tubs(
"solid" + wallName, wallRmin * CLHEP::cm,
204 wallRmax * CLHEP::cm, length * CLHEP::cm, 0 * CLHEP::deg, 360.*CLHEP::deg);
206 G4LogicalVolume* outerWallTube =
new G4LogicalVolume(outerWallTubeShape, medWall,
"solid" + wallName, 0, 0, 0);
207 outerWallTube->SetVisAttributes(m_VisAttributes.back());
208 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (length + wallZbwd)*CLHEP::cm), outerWallTube,
"logical" + wallName,
209 logical_cdc,
false, iOuterWall);
213 m_VisAttributes.push_back(
new G4VisAttributes(
true, G4Colour(0., 1., 0.)));
215 const string wallName = wall.getName();
216 const double wallRmin = wall.getRmin();
217 const double wallRmax = wall.getRmax();
218 const double wallZfwd = wall.getZfwd();
219 const double wallZbwd = wall.getZbwd();
220 const double length = (wallZfwd - wallZbwd) / 2.0;
221 const int iInnerWall = wall.getId();
223 G4Material* medWall = medAir;
224 if (strstr(wallName.c_str(),
"MiddleWall") !=
nullptr) {
227 }
else if (strstr(wallName.c_str(),
"MiddleGlue") !=
nullptr) {
230 medWall = medAluminum;
233 G4Tubs* innerWallTubeShape =
new G4Tubs(
"solid" + wallName, wallRmin * CLHEP::cm,
234 wallRmax * CLHEP::cm, length * CLHEP::cm, 0 * CLHEP::deg, 360.*CLHEP::deg);
235 G4LogicalVolume* innerWallTube =
new G4LogicalVolume(innerWallTubeShape, medWall,
"logical" + wallName, 0, 0, 0);
236 innerWallTube->SetVisAttributes(m_VisAttributes.back());
237 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (length + wallZbwd)*CLHEP::cm), innerWallTube,
"physical" + wallName,
238 logical_cdc,
false, iInnerWall);
250 for (
int iSLayer = 0; iSLayer < nSLayer; ++iSLayer) {
254 double rmin_sensitive_left, rmax_sensitive_left;
255 double rmin_sensitive_middle, rmax_sensitive_middle;
256 double rmin_sensitive_right, rmax_sensitive_right;
257 double zback_sensitive_left, zfor_sensitive_left;
258 double zback_sensitive_middle, zfor_sensitive_middle;
259 double zback_sensitive_right, zfor_sensitive_right;
262 const auto& epLayerBwd = endplate.getEndPlateLayer(0);
263 const auto& epLayerFwd = endplate.getEndPlateLayer(nEPLayer / 2);
267 rmin_sensitive_left = epLayerBwd.getRmax();
268 rmax_sensitive_left = fieldLayer.
getR();
269 zback_sensitive_left = senseLayer.getZbwd();
270 zfor_sensitive_left = epLayerBwd.getZfwd();
272 rmin_sensitive_middle = (geo.
getInnerWall(0)).getRmax();
273 rmax_sensitive_middle = fieldLayer.getR();
274 zback_sensitive_middle = epLayerBwd.getZbwd();
275 zfor_sensitive_middle = epLayerFwd.getZbwd();
277 rmin_sensitive_right = epLayerFwd.getRmax();
278 rmax_sensitive_right = fieldLayer.getR();
279 zback_sensitive_right = epLayerFwd.getZbwd();
280 zfor_sensitive_right = senseLayer.getZfwd();
281 }
else if (iSLayer >= 1 && iSLayer <= 14) {
282 const auto& epLayerBwd = endplate.getEndPlateLayer(1);
283 const auto& epLayerFwd = endplate.getEndPlateLayer((nEPLayer / 2) + 1);
288 rmin_sensitive_left = epLayerBwd.getRmax();
289 rmax_sensitive_left = fieldLayerOut.
getR();
290 zback_sensitive_left = senseLayer.getZbwd();
291 zfor_sensitive_left = epLayerBwd.getZfwd();
293 rmin_sensitive_middle = fieldLayerIn.getR();
294 rmax_sensitive_middle = fieldLayerOut.getR();
295 zback_sensitive_middle = epLayerBwd.getZfwd();
296 zfor_sensitive_middle = epLayerFwd.getZbwd();
298 rmin_sensitive_right = epLayerFwd.getRmax();
299 rmax_sensitive_right = fieldLayerOut.getR();
300 zback_sensitive_right = epLayerFwd.getZbwd();
301 zfor_sensitive_right = senseLayer.getZfwd();
302 }
else if (iSLayer >= 15 && iSLayer <= 18) {
303 const auto& epLayerBwd = endplate.getEndPlateLayer(1);
304 const auto& epLayerFwd = endplate.getEndPlateLayer(nEPLayer / 2);
309 rmin_sensitive_left = epLayerBwd.getRmax();
310 rmax_sensitive_left = fieldLayerOut.
getR();
311 zback_sensitive_left = senseLayer.getZbwd();
312 zfor_sensitive_left = epLayerBwd.getZfwd();
314 rmin_sensitive_middle = fieldLayerIn.getR();
315 rmax_sensitive_middle = fieldLayerOut.getR();
316 zback_sensitive_middle = epLayerBwd.getZfwd();
317 zfor_sensitive_middle = epLayerFwd.getZbwd();
319 rmin_sensitive_right = epLayerFwd.getRmax();
320 rmax_sensitive_right = fieldLayerOut.getR();
321 zback_sensitive_right = epLayerFwd.getZbwd();
322 zfor_sensitive_right = senseLayer.getZfwd();
323 }
else if (iSLayer >= 19 && iSLayer < 55) {
324 const auto& epLayerBwd = endplate.getEndPlateLayer(0);
325 const auto& epLayerFwd = endplate.getEndPlateLayer(nEPLayer / 2);
330 rmin_sensitive_left = epLayerBwd.getRmax();
331 rmax_sensitive_left = fieldLayerOut.
getR();
332 zback_sensitive_left = senseLayer.getZbwd();
333 zfor_sensitive_left = epLayerBwd.getZfwd();
335 rmin_sensitive_middle = fieldLayerIn.getR();
336 rmax_sensitive_middle = fieldLayerOut.getR();
337 zback_sensitive_middle = epLayerBwd.getZfwd();
338 zfor_sensitive_middle = epLayerFwd.getZbwd();
340 rmin_sensitive_right = epLayerFwd.getRmax();
341 rmax_sensitive_right = fieldLayerOut.getR();
342 zback_sensitive_right = epLayerFwd.getZbwd();
343 zfor_sensitive_right = senseLayer.getZfwd();
345 }
else if (iSLayer == 55) {
347 const auto& epLayerBwdIn = endplate.getEndPlateLayer(0);
348 const auto& epLayerBwdOut = endplate.getEndPlateLayer((nEPLayer / 2) - 1);
349 const auto& epLayerFwdIn = endplate.getEndPlateLayer(nEPLayer / 2);
350 const auto& epLayerFwdOut = endplate.getEndPlateLayer(nEPLayer - 1);
353 int iSLayerMinus1 = iSLayer - 1;
355 rmin_sensitive_left = epLayerBwdIn.getRmax();
356 rmax_sensitive_left = epLayerBwdOut.getRmax();
357 zback_sensitive_left = senseLayer.
getZbwd();
358 zfor_sensitive_left = epLayerBwdIn.getZfwd();
360 rmin_sensitive_middle = fieldLayerIn.getR();
361 rmax_sensitive_middle = (geo.
getOuterWall(0)).getRmin();
362 zback_sensitive_middle = epLayerBwdIn.getZfwd();
363 zfor_sensitive_middle = epLayerFwdIn.getZbwd();
365 rmin_sensitive_right = epLayerFwdIn.getRmax();
366 rmax_sensitive_right = epLayerFwdOut.getRmax();
367 zback_sensitive_right = epLayerFwdIn.getZbwd();
368 zfor_sensitive_right = senseLayer.getZfwd();
371 B2ERROR(
"Undefined sensitive layer : " << iSLayer);
377 if ((zfor_sensitive_left - zback_sensitive_left) > length_feedthrough) {
394 G4Tubs* leftTubeShape =
new G4Tubs((format(
"solidCDCLayer_%1%_leftTube") % iSLayer).str().c_str(), rmin_sensitive_left * CLHEP::cm,
395 rmax_sensitive_left * CLHEP::cm, length_feedthrough * CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
396 G4LogicalVolume* leftTube =
new G4LogicalVolume(leftTubeShape, cdcMed,
397 (format(
"logicalCDCLayer_%1%_leftTube") % iSLayer).str().c_str(), 0, 0, 0);
398 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zback_sensitive_left + length_feedthrough / 2.0)*CLHEP::cm), leftTube,
399 (format(
"physicalCDCLayer_%1%_leftTube") % iSLayer).str().c_str(), logical_cdc,
false, iSLayer);
401 G4Tubs* leftSensitiveTubeShape =
new G4Tubs((format(
"solidSD_CDCLayer_%1%_left") % iSLayer).str().c_str(),
402 rmin_sensitive_left * CLHEP::cm, rmax_sensitive_left * CLHEP::cm,
403 (zfor_sensitive_left - zback_sensitive_left - length_feedthrough)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
404 G4LogicalVolume* leftSensitiveTube =
new G4LogicalVolume(leftSensitiveTubeShape, cdcMed,
405 (format(
"logicalSD_CDCLayer_%1%_left") % iSLayer).str().c_str(), 0, 0, 0);
406 leftSensitiveTube->SetSensitiveDetector(m_sensitive);
407 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfor_sensitive_left + zback_sensitive_left + length_feedthrough)*CLHEP::cm / 2.0),
408 leftSensitiveTube, (format(
"physicalSD_CDCLayer_%1%_left") % iSLayer).str().c_str(), logical_cdc,
false, iSLayer);
426 G4Tubs* leftTubeShape =
new G4Tubs((format(
"solidCDCLayer_%1%_leftTube") % iSLayer).str().c_str(), rmin_sensitive_left * CLHEP::cm,
427 rmax_sensitive_left * CLHEP::cm, (zfor_sensitive_left - zback_sensitive_left)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
428 G4LogicalVolume* leftTube =
new G4LogicalVolume(leftTubeShape, cdcMed,
429 (format(
"logicalCDCLayer_%1%_leftTube") % iSLayer).str().c_str(), 0, 0, 0);
430 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfor_sensitive_left + zback_sensitive_left)*CLHEP::cm / 2.0), leftTube,
431 (format(
"physicalCDCLayer_%1%_leftTube") % iSLayer).str().c_str(), logical_cdc,
false, iSLayer);
435 G4Tubs* leftMidTubeShape =
new G4Tubs((format(
"solidCDCLayer_%1%_leftMidTube") % iSLayer).str().c_str(),
436 rmin_sensitive_middle * CLHEP::cm, rmax_sensitive_middle * CLHEP::cm,
437 (length_feedthrough - zfor_sensitive_left + zback_sensitive_left)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
438 G4LogicalVolume* leftMidTube =
new G4LogicalVolume(leftMidTubeShape, cdcMed,
439 (format(
"logicalCDCLayer_%1%_leftMidTube") % iSLayer).str().c_str(), 0, 0, 0);
441 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (length_feedthrough + zfor_sensitive_left + zback_sensitive_left)*CLHEP::cm / 2.0),
442 leftMidTube, (format(
"physicalCDCLayer_%1%_leftMidTube") % iSLayer).str().c_str(), logical_cdc,
false, iSLayer);
445 zback_sensitive_middle = length_feedthrough + zback_sensitive_left;
449 if ((zfor_sensitive_right - zback_sensitive_right) > length_feedthrough) {
466 G4Tubs* rightTubeShape =
new G4Tubs((format(
"solidCDCLayer_%1%_rightTube") % iSLayer).str().c_str(),
467 rmin_sensitive_right * CLHEP::cm, rmax_sensitive_right * CLHEP::cm, length_feedthrough * CLHEP::cm / 2.0, 0 * CLHEP::deg,
469 G4LogicalVolume* rightTube =
new G4LogicalVolume(rightTubeShape, cdcMed,
470 (format(
"logicalCDCLayer_%1%_rightTube") % iSLayer).str().c_str(), 0, 0, 0);
472 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfor_sensitive_right - length_feedthrough / 2.0)*CLHEP::cm), rightTube,
473 (format(
"physicalCDCLayer_%1%_rightTube") % iSLayer).str().c_str(), logical_cdc,
false, iSLayer);
477 G4Tubs* rightSensitiveTubeShape =
new G4Tubs((format(
"solidSD_CDCLayer_%1%_right") % iSLayer).str().c_str(),
478 rmin_sensitive_right * CLHEP::cm, rmax_sensitive_right * CLHEP::cm,
479 (zfor_sensitive_right - zback_sensitive_right - length_feedthrough)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
480 G4LogicalVolume* rightSensitiveTube =
new G4LogicalVolume(rightSensitiveTubeShape, cdcMed,
481 (format(
"logicalSD_CDCLayer_%1%_right") % iSLayer).str().c_str(), 0, 0, 0);
482 rightSensitiveTube->SetSensitiveDetector(m_sensitive);
484 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfor_sensitive_right + zback_sensitive_right - length_feedthrough)*CLHEP::cm / 2.0),
485 rightSensitiveTube, (format(
"physicalSD_CDCLayer_%1%_right") % iSLayer).str().c_str(), logical_cdc,
false, iSLayer);
504 G4Tubs* rightTubeShape =
new G4Tubs((format(
"solidCDCLayer_%1%_rightTube") % iSLayer).str().c_str(),
505 rmin_sensitive_right * CLHEP::cm, rmax_sensitive_right * CLHEP::cm, (zfor_sensitive_right - zback_sensitive_right)*CLHEP::cm / 2.0,
506 0 * CLHEP::deg, 360.*CLHEP::deg);
507 G4LogicalVolume* rightTube =
new G4LogicalVolume(rightTubeShape, cdcMed,
508 (format(
"logicalCDCLayer_%1%_rightTube") % iSLayer).str().c_str(), 0, 0, 0);
510 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfor_sensitive_right + zback_sensitive_right)*CLHEP::cm / 2.0), rightTube,
511 (format(
"physicalCDCLayer_%1%_rightTube") % iSLayer).str().c_str(), logical_cdc,
false, iSLayer);
515 G4Tubs* rightMidTubeShape =
new G4Tubs((format(
"solidCDCLayer_%1%_rightMidTube") % iSLayer).str().c_str(),
516 rmin_sensitive_middle * CLHEP::cm, rmax_sensitive_middle * CLHEP::cm,
517 (length_feedthrough - zfor_sensitive_right + zback_sensitive_right)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
518 G4LogicalVolume* rightMidTube =
new G4LogicalVolume(rightMidTubeShape, cdcMed,
519 (format(
"logicalCDCLayer_%1%_rightMidTube") % iSLayer).str().c_str(), 0, 0, 0);
520 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zback_sensitive_right - length_feedthrough + zfor_sensitive_right)*CLHEP::cm / 2.0),
521 rightMidTube, (format(
"physicalCDCLayer_%1%_rightMidTube") % iSLayer).str().c_str(), logical_cdc,
false, iSLayer);
524 zfor_sensitive_middle = zfor_sensitive_right - length_feedthrough;
529 G4Tubs* middleSensitiveTubeShape =
new G4Tubs((format(
"solidSD_CDCLayer_%1%_middle") % iSLayer).str().c_str(),
530 rmin_sensitive_middle * CLHEP::cm, rmax_sensitive_middle * CLHEP::cm,
531 (zfor_sensitive_middle - zback_sensitive_middle)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
532 G4LogicalVolume* middleSensitiveTube =
new G4LogicalVolume(middleSensitiveTubeShape, cdcMedGas,
533 (format(
"logicalSD_CDCLayer_%1%_middle") % iSLayer).str().c_str(), 0, 0, 0);
536 G4UserLimits* uLimits =
new G4UserLimits(8.5 * CLHEP::cm);
537 m_userLimits.push_back(uLimits);
538 middleSensitiveTube->SetUserLimits(uLimits);
539 middleSensitiveTube->SetSensitiveDetector(m_sensitive);
541 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfor_sensitive_middle + zback_sensitive_middle)*CLHEP::cm / 2.0), middleSensitiveTube,
542 (format(
"physicalSD_CDCLayer_%1%_middle") % iSLayer).str().c_str(), logical_cdc,
false, iSLayer);
546 G4String sName =
"sWire";
551 G4double tAtZ0 = -wb0.Z() / (wf0.Z() - wb0.Z());
552 TVector3 wAtZ0 = wb0 + tAtZ0 * (wf0 - wb0);
554 const G4double epsl = 25.e-4;
555 G4double reductionBwd = (zback_sensitive_middle + epsl) / wb0.Z();
557 wb0 = reductionBwd * (wb0 - wAtZ0) + wAtZ0;
559 G4double reductionFwd = (zfor_sensitive_middle - epsl) / wf0.Z();
560 wf0 = reductionFwd * (wf0 - wAtZ0) + wAtZ0;
562 const G4double wireHalfLength = 0.5 * (wf0 - wb0).Mag() * CLHEP::cm;
565 G4Tubs* middleSensitiveSwireShape =
new G4Tubs(sName, 0., sWireRadius, wireHalfLength, 0., 360. * CLHEP::deg);
566 G4LogicalVolume* middleSensitiveSwire =
new G4LogicalVolume(middleSensitiveSwireShape, medTungsten, sName);
568 middleSensitiveSwire->SetVisAttributes(m_VisAttributes.front());
570 G4String fName =
"fWire";
572 G4Tubs* middleSensitiveFwireShape =
new G4Tubs(fName, 0., fWireRadius, wireHalfLength, 0., 360. * CLHEP::deg);
573 G4LogicalVolume* middleSensitiveFwire =
new G4LogicalVolume(middleSensitiveFwireShape, medAluminum, fName);
575 middleSensitiveFwire->SetVisAttributes(m_VisAttributes.front());
580 const G4double dphi = M_PI / nCells;
581 const TVector3 unitZ(0., 0., 1.);
583 for (
int ic = 0; ic < nCells; ++ic) {
587 G4double tAtZ02 = -wb.Z() / (wf.Z() - wb.Z());
588 TVector3 wAtZ02 = wb + tAtZ02 * (wf - wb);
589 G4double reductionBwd2 = (zback_sensitive_middle + epsl) / wb.Z();
590 wb = reductionBwd2 * (wb - wAtZ02) + wAtZ02;
591 G4double reductionFwd2 = (zfor_sensitive_middle - epsl) / wf.Z();
592 wf = reductionFwd2 * (wf - wAtZ02) + wAtZ02;
594 G4double thetaYZ = -asin((wf - wb).Y() / (wf - wb).Mag());
596 TVector3 fMinusBInZX((wf - wb).X(), 0., (wf - wb).Z());
597 G4double thetaZX = asin((unitZ.Cross(fMinusBInZX)).Y() / fMinusBInZX.Mag());
598 G4RotationMatrix rotM;
600 rotM.rotateX(thetaYZ * CLHEP::rad);
601 rotM.rotateY(thetaZX * CLHEP::rad);
603 G4ThreeVector xyz(0.5 * (wb.X() + wf.X()) * CLHEP::cm,
604 0.5 * (wb.Y() + wf.Y()) * CLHEP::cm, 0.);
608 new G4PVPlacement(G4Transform3D(rotM, xyz), middleSensitiveSwire, sName, middleSensitiveTube,
false, ic);
612 G4double rF = rmax_sensitive_middle - 0.5 * diameter;
614 G4double phi = atan2(wbF.Y(), wbF.X());
615 wbF.SetX(rF * cos(phi));
616 wbF.SetY(rF * sin(phi));
619 rF = rmax_sensitive_middle - 0.5 * diameter;
620 phi = atan2(wfF.Y(), wfF.X());
621 wfF.SetX(rF * cos(phi));
622 wfF.SetY(rF * sin(phi));
624 thetaYZ = -asin((wfF - wbF).Y() / (wfF - wbF).Mag());
626 fMinusBInZX = wfF - wbF;
627 fMinusBInZX.SetY(0.);
628 thetaZX = asin((unitZ.Cross(fMinusBInZX)).Y() / fMinusBInZX.Mag());
630 G4RotationMatrix rotM1;
631 rotM1.rotateX(thetaYZ * CLHEP::rad);
632 rotM1.rotateY(thetaZX * CLHEP::rad);
634 xyz.setX(0.5 * (wbF.X() + wfF.X()) * CLHEP::cm);
635 xyz.setY(0.5 * (wbF.Y() + wfF.Y()) * CLHEP::cm);
637 if (iSLayer != nSLayer - 1) {
639 new G4PVPlacement(G4Transform3D(rotM1, xyz), middleSensitiveFwire, fName, middleSensitiveTube,
false, ic);
645 phi = atan2(wbF.Y(), wbF.X());
646 wbF.SetX(rF * cos(phi + dphi));
647 wbF.SetY(rF * sin(phi + dphi));
651 phi = atan2(wfF.Y(), wfF.X());
652 wfF.SetX(rF * cos(phi + dphi));
653 wfF.SetY(rF * sin(phi + dphi));
655 thetaYZ = -asin((wfF - wbF).Y() / (wfF - wbF).Mag());
657 fMinusBInZX = wfF - wbF;
658 fMinusBInZX.SetY(0.);
659 thetaZX = asin((unitZ.Cross(fMinusBInZX)).Y() / fMinusBInZX.Mag());
661 G4RotationMatrix rotM2;
662 rotM2.rotateX(thetaYZ * CLHEP::rad);
663 rotM2.rotateY(thetaZX * CLHEP::rad);
665 xyz.setX(0.5 * (wbF.X() + wfF.X()) * CLHEP::cm);
666 xyz.setY(0.5 * (wbF.Y() + wfF.Y()) * CLHEP::cm);
669 new G4PVPlacement(G4Transform3D(rotM2, xyz), middleSensitiveFwire, fName, middleSensitiveTube,
false, ic + nCells);
673 rF = rmax_sensitive_middle - 0.5 * diameter;
674 phi = atan2(wbF.Y(), wbF.X());
675 wbF.SetX(rF * cos(phi + dphi));
676 wbF.SetY(rF * sin(phi + dphi));
679 rF = rmax_sensitive_middle - 0.5 * diameter;
680 phi = atan2(wfF.Y(), wfF.X());
681 wfF.SetX(rF * cos(phi + dphi));
682 wfF.SetY(rF * sin(phi + dphi));
684 thetaYZ = -asin((wfF - wbF).Y() / (wfF - wbF).Mag());
686 fMinusBInZX = wfF - wbF;
687 fMinusBInZX.SetY(0.);
688 thetaZX = asin((unitZ.Cross(fMinusBInZX)).Y() / fMinusBInZX.Mag());
690 G4RotationMatrix rotM3;
691 rotM3.rotateX(thetaYZ * CLHEP::rad);
692 rotM3.rotateY(thetaZX * CLHEP::rad);
694 xyz.setX(0.5 * (wbF.X() + wfF.X()) * CLHEP::cm);
695 xyz.setY(0.5 * (wbF.Y() + wfF.Y()) * CLHEP::cm);
697 if (iSLayer != nSLayer - 1) {
698 new G4PVPlacement(G4Transform3D(rotM3, xyz), middleSensitiveFwire, fName, middleSensitiveTube,
false, ic + 2 * nCells);
708 m_VisAttributes.push_back(
new G4VisAttributes(
true, G4Colour(1., 1., 0.)));
710 for (
const auto& epLayer : endplate.getEndPlateLayers()) {
711 const int iEPLayer = epLayer.getILayer();
712 const string name = epLayer.getName();
713 const double rmin = epLayer.getRmin();
714 const double rmax = epLayer.getRmax();
715 const double zbwd = epLayer.getZbwd();
716 const double zfwd = epLayer.getZfwd();
717 const double length = (zfwd - zbwd) / 2.0;
719 G4Tubs* tube =
new G4Tubs(
"solidCDCEndplate" + name, rmin * CLHEP::cm,
720 rmax * CLHEP::cm, length * CLHEP::cm, 0 * CLHEP::deg, 360.*CLHEP::deg);
721 G4LogicalVolume* logical =
new G4LogicalVolume(tube, Materials::get(
"G4_Al"),
722 "logicalCDCEndplate" + name, 0, 0);
723 logical->SetVisAttributes(m_VisAttributes.back());
724 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfwd + zbwd)*CLHEP::cm / 2.0), logical,
725 "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);
1012 logicalV->SetSensitiveDetector(sensitiveDetector);
1013 m_BkgSensitiveRib4.push_back(sensitiveDetector);
1016 logicalV->SetVisAttributes(m_VisAttributes.back());
1018 const double phi = 360.0 / ndiv;
1020 G4RotationMatrix rot = G4RotationMatrix();
1021 G4ThreeVector arm(x * CLHEP::cm, y * CLHEP::cm, z * CLHEP::cm - thick * CLHEP::cm / 2.0);
1024 rot.rotateZ(0.5 * phi * CLHEP::deg);
1025 arm.rotateZ(0.5 * phi * CLHEP::deg);
1027 for (
int i = 0; i < ndiv; ++i) {
1028 const string physicalName =
"physicalRib4_" + to_string(
id) +
" " + to_string(i);
1029 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
1030 physicalName.c_str(), logical_cdc,
false,
id);
1031 rot.rotateZ(phi * CLHEP::deg);
1032 arm.rotateZ(phi * CLHEP::deg);
1039 for (
const auto& rib5 : geo.
getRib5s()) {
1041 const int id = rib5.getId();
1042 const double dr = rib5.getDr();
1043 const double dz = rib5.getDz();
1044 const double width = rib5.getWidth();
1045 const double thick = rib5.getThick();
1046 const double rin = rib5.getRin();
1047 const double x = rib5.getX();
1048 const double y = rib5.getY();
1049 const double z = rib5.getZ();
1050 const double rotx = rib5.getRotx();
1051 const double roty = rib5.getRoty();
1052 const double rotz = rib5.getRotz();
1053 const int offset = rib5.getOffset();
1054 const int ndiv = rib5.getNDiv();
1056 const string solidName =
"solidRib5" + to_string(
id);
1057 const string logicalName =
"logicalRib5" + to_string(
id);
1059 const double rmax = rin + thick;
1060 const double rmin = rin;
1061 const double dphi = 2. * atan2(dz, dr);
1062 const double ddphi = thick * tan(dphi) / rin;
1063 const double ddphi2 = width / 2. * width / 2. / (x + dr) / rin;
1064 const double cphi = dphi - ddphi - ddphi2;
1065 G4Tubs* tubeShape =
new G4Tubs(solidName,
1068 0.5 * width * CLHEP::cm,
1072 G4LogicalVolume* logicalV =
new G4LogicalVolume(tubeShape, medAluminum, logicalName, 0, 0, 0);
1074 logicalV->SetVisAttributes(m_VisAttributes.back());
1076 const double phi = 360.0 / ndiv;
1078 G4RotationMatrix rot = G4RotationMatrix();
1081 G4ThreeVector arm(x * CLHEP::cm, y * CLHEP::cm, z * CLHEP::cm - rin * CLHEP::cm - thick * CLHEP::cm);
1086 rot.rotateZ(0.5 * phi * CLHEP::deg);
1087 arm.rotateZ(0.5 * phi * CLHEP::deg);
1089 for (
int i = 0; i < ndiv; ++i) {
1090 const string physicalName =
"physicalRib5_" + to_string(
id) +
" " + to_string(i);
1091 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
1092 physicalName.c_str(), logical_cdc,
false,
id);
1093 rot.rotateZ(phi * CLHEP::deg);
1094 arm.rotateZ(phi * CLHEP::deg);
1100 createMapper(topVolume);
1104 void GeoCDCCreator::createNeutronShields(
const GearDir& content)
1107 G4Material* C2H4 = geometry::Materials::get(
"G4_POLYETHYLENE");
1108 G4Material* elB = geometry::Materials::get(
"G4_B");
1112 G4Material* boratedpoly05 =
new G4Material(
"BoratedPoly05", 1.06 * CLHEP::g / CLHEP::cm3, 2);
1113 boratedpoly05->AddMaterial(elB, 0.05);
1114 boratedpoly05->AddMaterial(C2H4, 0.95);
1116 G4Material* boratedpoly30 =
new G4Material(
"BoratedPoly30", 1.19 * CLHEP::g / CLHEP::cm3, 2);
1117 boratedpoly30->AddMaterial(elB, 0.30);
1118 boratedpoly30->AddMaterial(C2H4, 0.70);
1120 G4Material* shieldMat = C2H4;
1122 const int nShields = content.getNumberNodes(
"Shields/Shield");
1124 for (
int iShield = 0; iShield < nShields; ++iShield) {
1125 GearDir shieldContent(content);
1126 shieldContent.
append((format(
"/Shields/Shield[%1%]/") % (iShield + 1)).str());
1127 const string sShieldID = shieldContent.
getString(
"@id");
1128 const int shieldID = atoi(sShieldID.c_str());
1130 const double shieldInnerR1 = shieldContent.
getLength(
"InnerR1");
1131 const double shieldInnerR2 = shieldContent.
getLength(
"InnerR2");
1132 const double shieldOuterR1 = shieldContent.
getLength(
"OuterR1");
1133 const double shieldOuterR2 = shieldContent.
getLength(
"OuterR2");
1134 const double shieldThick = shieldContent.
getLength(
"Thickness");
1135 const double shieldPosZ = shieldContent.
getLength(
"PosZ");
1137 G4Cons* shieldConsShape =
new G4Cons((format(
"solidShield%1%") % shieldID).str().c_str(),
1138 shieldInnerR1 * CLHEP::cm, shieldOuterR1 * CLHEP::cm,
1139 shieldInnerR2 * CLHEP::cm, shieldOuterR2 * CLHEP::cm,
1140 shieldThick * CLHEP::cm / 2.0,
1141 0.*CLHEP::deg, 360.*CLHEP::deg);
1143 G4LogicalVolume* shieldCons =
new G4LogicalVolume(shieldConsShape, shieldMat, (format(
"logicalShield%1%") % shieldID).str().c_str(),
1145 shieldCons->SetVisAttributes(m_VisAttributes.back());
1146 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (shieldPosZ - shieldThick / 2.0) * CLHEP::cm), shieldCons,
1147 (format(
"physicalShield%1%") % shieldID).str().c_str(), logical_cdc,
false, 0);
1157 G4Material* C2H4 = geometry::Materials::get(
"G4_POLYETHYLENE");
1158 G4Material* shieldMat = C2H4;
1160 for (
const auto& shield : geom.getNeutronShields()) {
1161 const int shieldID = shield.getId();
1162 const double shieldInnerR1 = shield.getRmin1();
1163 const double shieldInnerR2 = shield.getRmin2();
1164 const double shieldOuterR1 = shield.getRmax1();
1165 const double shieldOuterR2 = shield.getRmax2();
1166 const double shieldThick = shield.getThick();
1167 const double shieldPosZ = shield.getZ();
1169 G4Cons* shieldConsShape =
new G4Cons(
"solidShield" + to_string(shieldID),
1170 shieldInnerR1 * CLHEP::cm, shieldOuterR1 * CLHEP::cm,
1171 shieldInnerR2 * CLHEP::cm, shieldOuterR2 * CLHEP::cm,
1172 shieldThick * CLHEP::cm / 2.0,
1173 0.*CLHEP::deg, 360.*CLHEP::deg);
1175 G4LogicalVolume* shieldCons =
new G4LogicalVolume(shieldConsShape, shieldMat,
"logicalShield" + to_string(shieldID),
1177 shieldCons->SetVisAttributes(m_VisAttributes.back());
1178 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (shieldPosZ - shieldThick / 2.0) * CLHEP::cm), shieldCons,
1179 "physicalShield" + to_string(shieldID), logical_cdc,
false, 0);
1185 void GeoCDCCreator::createCovers(
const GearDir& content)
1187 string Aluminum = content.getString(
"Aluminum");
1188 G4Material* medAluminum = geometry::Materials::get(Aluminum);
1189 G4Material* medNEMA_G10_Plate = geometry::Materials::get(
"NEMA_G10_Plate");
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);
1198 G4Material* medCopper = geometry::Materials::get(
"Cu");
1199 G4Material* medLV = geometry::Materials::get(
"CDCLVCable");
1200 G4Material* medFiber = geometry::Materials::get(
"CDCOpticalFiber");
1201 G4Material* medCAT7 = geometry::Materials::get(
"CDCCAT7");
1202 G4Material* medTRG = geometry::Materials::get(
"CDCOpticalFiberTRG");
1203 G4Material* medHV = geometry::Materials::get(
"CDCHVCable");
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((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((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((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);
1336 logicalV->SetVisAttributes(m_VisAttributes.back());
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,
1356 physicalName.c_str(), logical_cdc,
false, ribID);
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((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);
1396 logicalV->SetVisAttributes(m_VisAttributes.back());
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,
1409 physicalName.c_str(), logical_cdc,
false, rib2ID);
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((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);
1458 logicalV->SetVisAttributes(m_VisAttributes.back());
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,
1472 physicalName.c_str(), logical_cdc,
false, rib3ID);
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((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);
1526 logicalV->SetVisAttributes(m_VisAttributes.back());
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,
1540 physicalName.c_str(), logical_cdc,
false, rib4ID);
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((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);
1585 logicalV->SetVisAttributes(m_VisAttributes.back());
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,
1604 physicalName.c_str(), logical_cdc,
false, rib5ID);
1605 rot.rotateZ(phi * CLHEP::deg);
1606 arm.rotateZ(phi * CLHEP::deg);
1615 G4Material* medAl = geometry::Materials::get(
"Al");
1616 G4double density = 1.000 * CLHEP::g / CLHEP::cm3;
1617 G4double a = 1.01 * CLHEP::g / CLHEP::mole;
1618 G4Element* elH =
new G4Element(
"Hydrogen",
"H", 1., a);
1619 a = 16.00 * CLHEP::g / CLHEP::mole;
1620 G4Element* elO =
new G4Element(
"Oxygen",
"O", 8., a);
1621 G4Material* medH2O =
new G4Material(
"water", density, 2);
1622 medH2O->AddElement(elH, 2);
1623 medH2O->AddElement(elO, 1);
1624 G4Material* medCu = geometry::Materials::get(
"Cu");
1625 G4Material* medLV = geometry::Materials::get(
"CDCLVCable");
1626 G4Material* medFiber = geometry::Materials::get(
"CDCOpticalFiber");
1627 G4Material* medCAT7 = geometry::Materials::get(
"CDCCAT7");
1628 G4Material* medTRG = geometry::Materials::get(
"CDCOpticalFiberTRG");
1629 G4Material* medHV = geometry::Materials::get(
"CDCHVCable");
1631 m_VisAttributes.push_back(
new G4VisAttributes(
true, G4Colour(0., 1., 0.)));
1632 for (
const auto& cover : geom.getCovers()) {
1633 const int coverID = cover.getId();
1634 const string coverName =
"cover" + to_string(coverID);
1635 const double rmin1 = cover.getRmin1();
1636 const double rmin2 = cover.getRmin2();
1637 const double rmax1 = cover.getRmax1();
1638 const double rmax2 = cover.getRmax2();
1639 const double thick = cover.getThick();
1640 const double posZ = cover.getZ();
1649 if (coverID == 7 || coverID == 10) {
1650 createCone(rmin1, rmax1, rmin2, rmax2, thick, posZ, coverID, medAl, coverName);
1652 createTube(rmin1, rmax1, thick, posZ, coverID, medAl, coverName);
1655 if (coverID > 22 && coverID < 29)
1656 createTube(rmin1, rmax1, thick, posZ, coverID, medCu, coverName);
1657 if (coverID > 28 && coverID < 35)
1658 createTorus(rmin1, rmax1, thick, posZ, coverID, medCu, coverName);
1659 if (coverID > 34 && coverID < 41)
1660 createTorus(rmin1, rmax1, thick, posZ, coverID, medH2O, coverName);
1661 if (coverID == 45 || coverID == 46)
1662 createTube(rmin1, rmax1, thick, posZ, coverID, medLV, coverName);
1663 if (coverID == 47 || coverID == 48)
1664 createTube(rmin1, rmax1, thick, posZ, coverID, medFiber, coverName);
1665 if (coverID == 49 || coverID == 50)
1666 createTube(rmin1, rmax1, thick, posZ, coverID, medCAT7, coverName);
1667 if (coverID == 51 || coverID == 52)
1668 createTube(rmin1, rmax1, thick, posZ, coverID, medTRG, coverName);
1670 createTube(rmin1, rmax1, thick, posZ, coverID, medHV, coverName);
1676 G4Material* medHV = geometry::Materials::get(
"CDCHVCable");
1677 G4Material* medFiber = geometry::Materials::get(
"CDCOpticalFiber");
1678 G4Material* medCAT7 = geometry::Materials::get(
"CDCCAT7");
1679 G4Material* medTRG = geometry::Materials::get(
"CDCOpticalFiberTRG");
1681 m_VisAttributes.push_back(
new G4VisAttributes(
true, G4Colour(0., 1., 0.)));
1682 for (
const auto& cover2 : geom.getCover2s()) {
1683 const int cover2ID = cover2.getId();
1684 const string cover2Name =
"cover2" + to_string(cover2ID);
1685 const double rmin = cover2.getRmin();
1686 const double rmax = cover2.getRmax();
1687 const double phis = cover2.getPhis();
1688 const double dphi = cover2.getDphi();
1689 const double thick = cover2.getThick();
1690 const double posZ = cover2.getZ();
1693 createTube2(rmin, rmax, phis, dphi, thick, posZ, cover2ID, medHV, cover2Name);
1694 if (cover2ID > 10 && cover2ID < 14)
1695 createTube2(rmin, rmax, phis, dphi, thick, posZ, cover2ID, medFiber, cover2Name);
1696 if (cover2ID > 13 && cover2ID < 23)
1697 createTube2(rmin, rmax, phis, dphi, thick, posZ, cover2ID, medCAT7, cover2Name);
1698 if (cover2ID > 22 && cover2ID < 29)
1699 createTube2(rmin, rmax, phis, dphi, thick, posZ, cover2ID, medTRG, cover2Name);
1703 void GeoCDCCreator::createCone(
const double rmin1,
const double rmax1,
1704 const double rmin2,
const double rmax2,
1705 const double thick,
const double posZ,
1706 const int id, G4Material* med,
1709 const string solidName =
"solid" + name;
1710 const string logicalName =
"logical" + name;
1711 const string physicalName =
"physical" + name;
1712 G4Cons* coverConeShape =
new G4Cons(solidName.c_str(), rmin1 * CLHEP::cm, rmax1 * CLHEP::cm,
1713 rmin2 * CLHEP::cm, rmax2 * CLHEP::cm, thick * CLHEP::cm / 2.0, 0.*CLHEP::deg, 360.*CLHEP::deg);
1714 G4LogicalVolume* coverCone =
new G4LogicalVolume(coverConeShape, med,
1715 logicalName.c_str(), 0, 0, 0);
1716 coverCone->SetVisAttributes(m_VisAttributes.back());
1717 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, posZ * CLHEP::cm - thick * CLHEP::cm / 2.0), coverCone,
1718 physicalName.c_str(), logical_cdc,
false,
id);
1722 void GeoCDCCreator::createTube(
const double rmin,
const double rmax,
1723 const double thick,
const double posZ,
1724 const int id, G4Material* med,
1727 const string solidName =
"solid" + name;
1728 const string logicalName =
"logical" + name;
1729 const string physicalName =
"physical" + name;
1730 G4Tubs* solidV =
new G4Tubs(solidName.c_str(),
1733 thick * CLHEP::cm / 2.0,
1736 G4LogicalVolume* logicalV =
new G4LogicalVolume(solidV, med,
1737 logicalName.c_str(), 0, 0, 0);
1738 logicalV->SetVisAttributes(m_VisAttributes.back());
1739 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, posZ * CLHEP::cm - thick * CLHEP::cm / 2.0), logicalV,
1740 physicalName.c_str(), logical_cdc,
false,
id);
1744 void GeoCDCCreator::createBox(
const double length,
const double height,
1745 const double thick,
const double x,
1746 const double y,
const double z,
1747 const int id, G4Material* med,
1750 const string solidName = (format(
"solid%1%%2%") % name % id).str();
1751 const string logicalName = (format(
"logical%1%%2%") % name % id).str();
1752 const string physicalName = (format(
"physical%1%%2%") % name % id).str();
1753 G4Box* boxShape =
new G4Box(solidName.c_str(), 0.5 * length * CLHEP::cm,
1754 0.5 * height * CLHEP::cm,
1755 0.5 * thick * CLHEP::cm);
1756 G4LogicalVolume* logicalV =
new G4LogicalVolume(boxShape, med,
1757 logicalName.c_str(), 0, 0, 0);
1758 logicalV->SetVisAttributes(m_VisAttributes.back());
1759 new G4PVPlacement(0, G4ThreeVector(x * CLHEP::cm, y * CLHEP::cm, z * CLHEP::cm - thick * CLHEP::cm / 2.0), logicalV,
1760 physicalName.c_str(), logical_cdc,
false,
id);
1764 void GeoCDCCreator::createTorus(
const double rmin1,
const double rmax1,
1765 const double thick,
const double posZ,
1766 const int id, G4Material* med,
1769 const string solidName =
"solid" + name;
1770 const string logicalName =
"logical" + name;
1771 const string physicalName =
"physical" + name;
1772 const double rtor = (rmax1 + rmin1) / 2.;
1773 const double rmax = rmax1 - rtor;
1774 const double rmin = max((rmax - thick), 0.);
1776 G4Torus* solidV =
new G4Torus(solidName.c_str(),
1782 G4LogicalVolume* logicalV =
new G4LogicalVolume(solidV, med,
1783 logicalName.c_str(), 0, 0, 0);
1784 logicalV->SetVisAttributes(m_VisAttributes.back());
1785 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, posZ * CLHEP::cm), logicalV,
1786 physicalName.c_str(), logical_cdc,
false,
id);
1790 void GeoCDCCreator::createTube2(
const double rmin,
const double rmax,
1791 const double phis,
const double phie,
1792 const double thick,
const double posZ,
1793 const int id, G4Material* med,
1796 const string solidName =
"solid" + name;
1797 const string logicalName =
"logical" + name;
1798 const string physicalName =
"physical" + name;
1799 G4Tubs* solidV =
new G4Tubs(solidName.c_str(),
1802 thick * CLHEP::cm / 2.0,
1805 G4LogicalVolume* logicalV =
new G4LogicalVolume(solidV, med,
1806 logicalName.c_str(), 0, 0, 0);
1807 logicalV->SetVisAttributes(m_VisAttributes.back());
1808 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, posZ * CLHEP::cm - thick * CLHEP::cm / 2.0), logicalV,
1809 physicalName.c_str(), logical_cdc,
false,
id);
1813 void GeoCDCCreator::createMapper(G4LogicalVolume& topVolume)
1818 const double xc = 0.5 * (-0.0002769 + 0.0370499) * CLHEP::cm;
1819 const double yc = 0.5 * (-0.0615404 + -0.108948) * CLHEP::cm;
1820 const double zc = 0.5 * (-35.3 + 48.5) * CLHEP::cm;
1825 const double plateWidth = 13.8 * CLHEP::cm;
1826 const double plateThick = 1.2 * CLHEP::cm;
1827 const double plateLength = 83.8 * CLHEP::cm;
1833 const double endPlateRmin = 4.0 * CLHEP::cm;
1834 const double endPlateRmax = 15.5 * CLHEP::cm;
1835 const double bwdEndPlateThick = 1.7 * CLHEP::cm;
1836 const double fwdEndPlateThick = 2.0 * CLHEP::cm;
1838 G4Material* medAluminum = geometry::Materials::get(
"Al");
1840 string name =
"Plate";
1842 G4Box* plateShape =
new G4Box(
"solid" + name, .5 * plateWidth, .5 * plateThick, .5 * plateLength);
1843 G4LogicalVolume* logical0 =
new G4LogicalVolume(plateShape, medAluminum,
"logical" + name, 0, 0, 0);
1844 logical0->SetVisAttributes(m_VisAttributes.back());
1846 const double x = xc + 0.5 * plateWidth;
1848 const double y = yc + endPlateRmin + 0.1 * CLHEP::cm;
1850 G4ThreeVector xyz(x, y, zc);
1851 G4RotationMatrix rotM3 = G4RotationMatrix();
1854 new G4PVPlacement(G4Transform3D(rotM3, xyz), logical0,
"physical" + name, &topVolume,
false, pID);
1856 const double alf = 120. * CLHEP::deg;
1859 new G4PVPlacement(G4Transform3D(rotM3, xyz), logical0,
"physical" + name, &topVolume,
false, pID + 1);
1863 new G4PVPlacement(G4Transform3D(rotM3, xyz), logical0,
"physical" + name, &topVolume,
false, pID + 2);
1867 name =
"BwdEndPlate";
1868 G4Tubs* BwdEndPlateShape =
new G4Tubs(
"solid" + name, endPlateRmin, endPlateRmax, 0.5 * bwdEndPlateThick, 0., 360.*CLHEP::deg);
1869 G4LogicalVolume* logical1 =
new G4LogicalVolume(BwdEndPlateShape, medAluminum,
"logical" + name, 0, 0, 0);
1870 logical1->SetVisAttributes(m_VisAttributes.back());
1872 double z = -35.3 * CLHEP::cm - 0.5 * bwdEndPlateThick;
1874 new G4PVPlacement(0, G4ThreeVector(xc, yc, z), logical1,
"physical" + name, &topVolume,
false, pID);
1879 name =
"FwdEndPlate";
1880 G4Tubs* FwdEndPlateShape =
new G4Tubs(
"solid" + name, endPlateRmin, endPlateRmax, 0.5 * fwdEndPlateThick, 0., 360.*CLHEP::deg);
1881 G4LogicalVolume* logical2 =
new G4LogicalVolume(FwdEndPlateShape, medAluminum,
"logical" + name, 0, 0, 0);
1882 logical2->SetVisAttributes(m_VisAttributes.back());
1883 z = 48.5 * CLHEP::cm + 0.5 * fwdEndPlateThick;
1884 new G4PVPlacement(0, G4ThreeVector(xc, yc, z), logical2,
"physical" + name, &topVolume,
false, pID);
The Class for BeamBackground Sensitive Detector.
int getNEndPlateLayers() const
Get the number of endplate layers.
double getR() const
Get Radius.
double getZbwd() const
Get bwd z-position.
The Class for CDC geometry.
double getGlobalOffsetY() const
Get the global y offset of CDC wrt Belle2 coord.
FieldLayer getFieldLayer(int i) const
Get the i-th field layer.
std::vector< InnerWall > getInnerWalls() const
Get the list of inner walls.
std::vector< Rib2 > getRib2s() const
Get the list of rib2s.
OuterWall getOuterWall(int i) const
Get the i-th outer wall.
double getFiducialRmin() const
Get the fiducial Rmin of CDC sensitive volume.
double getGlobalOffsetX() const
Get the global x offset of CDC wrt Belle2 coord.
double getFiducialRmax() const
Get the fiducial Rmax of CDC sensitive volume.
int getNFieldWires() const
Get the number of field wires.
MotherVolume getMotherVolume() const
Get the mother volume geometry of CDC.
int getNSenseWires() const
Get the number of sense wires.
double getSenseDiameter() const
Get the diameter of sense wire.
std::vector< Rib5 > getRib5s() const
Get the list of rib5s.
InnerWall getInnerWall(int i) const
Get the i-th inner wall.
double getFieldDiameter() const
Get the diameter of field wire.
std::vector< Rib > getRibs() const
Get the list of ribs.
EndPlate getEndPlate(int i) const
Get the i-th endplate.
std::vector< EndPlate > getEndPlates() const
Get the list of endplates.
std::vector< Frontend > getFrontends() const
Get the list of frontend layers.
int getNSenseLayers() const
Get the number of sense layers.
double getFeedthroughLength() const
Get the length of feedthrough.
std::vector< Rib3 > getRib3s() const
Get the list of rib3s.
double getGlobalOffsetZ() const
Get the global z offset of CDC wrt Belle2 coord.
std::vector< Rib4 > getRib4s() const
Get the list of rib4s.
SenseLayer getSenseLayer(int i) const
Get i-th sense layer.
std::vector< OuterWall > getOuterWalls() const
Get the list of outer walls.
The Class for CDC Geometry Control Parameters.
bool getPrintMaterialTable() const
Get printMaterialTable flag.
double getMaterialDefinitionMode() const
Get material definition mode.
bool getMapperGeometry()
Get mapper geometry flag.
double getMapperPhiAngle()
Get mapper phi-angle.
The Class for CDC Geometry Parameters.
double fieldWireDiameter() const
Returns diameter of the field wire.
const TVector3 wireBackwardPosition(int layerId, int cellId, EWirePosition set=c_Base) const
Returns the backward position of the input sense wire.
const TVector3 wireForwardPosition(int layerId, int cellId, EWirePosition set=c_Base) const
Returns the forward position of the input sense wire.
double senseWireDiameter() const
Returns diameter of the sense wire.
unsigned nWiresInLayer(int layerId) const
Returns wire numbers in a layer.
The Class for CDC Sensitive Detector.
GearDir is the basic class used for accessing the parameter store.
void append(const std::string &path)
Append something to the current path, modifying the GearDir in place.
virtual std::string getString(const std::string &path="") const noexcept(false) override
Get the parameter path as a string.
double getLength(const std::string &path="") const noexcept(false)
Get the parameter path as a double converted to the standard length unit.
geometry::CreatorFactory< GeoCDCCreator > GeoCDCFactory("CDCCreator")
Register the GeoCreator.
GeometryTypes
Flag indiciating the type of geometry to be used.
Abstract base class for different kinds of events.
Very simple class to provide an easy way to register creators with the CreatorManager.