9#include <cdc/geometry/GeoCDCCreatorReducedCDC.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>
32#include <G4Polycone.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>
52 using namespace geometry;
78 B2WARNING(
"Using CDC without SL0!");
88 for (G4UserLimits* userLimits :
m_userLimits)
delete userLimits;
97 const G4double realTemperture = (273.15 + 23.) * CLHEP::kelvin;
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);
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 m_logicalCDC =
new G4LogicalVolume(solid_cdc, medAir,
"logicalCDC", 0, 0, 0);
178 "physicalCDC", &topVolume,
false, 0);
181 G4Region* aRegion =
new G4Region(
"CDCEnvelope");
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;
197 if (strstr((wallName).c_str(),
"MiddleWall") !=
nullptr) {
200 medWall = medAluminum;
202 G4Tubs* outerWallTubeShape =
new G4Tubs(
"solid" + wallName, wallRmin * CLHEP::cm,
203 wallRmax * CLHEP::cm, length * CLHEP::cm, 0 * CLHEP::deg, 360.*CLHEP::deg);
205 G4LogicalVolume* outerWallTube =
new G4LogicalVolume(outerWallTubeShape, medWall,
"solid" + wallName, 0, 0, 0);
207 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (length + wallZbwd)*CLHEP::cm), outerWallTube,
"logical" + wallName,
212 m_VisAttributes.push_back(
new G4VisAttributes(
true, G4Colour(0., 1., 0.)));
214 const string wallName = wall.getName();
215 const double wallRmin = wall.getRmin();
216 const double wallRmax = wall.getRmax();
217 const double wallZfwd = wall.getZfwd();
218 const double wallZbwd = wall.getZbwd();
219 const double length = (wallZfwd - wallZbwd) / 2.0;
220 const int iInnerWall = wall.getId();
223 if (strstr(wallName.c_str(),
"MiddleWall") !=
nullptr) {
225 }
else if (strstr(wallName.c_str(),
"MiddleGlue") !=
nullptr) {
228 medWall = medAluminum;
231 G4Tubs* innerWallTubeShape =
new G4Tubs(
"solid" + wallName, wallRmin * CLHEP::cm,
232 wallRmax * CLHEP::cm, length * CLHEP::cm, 0 * CLHEP::deg, 360.*CLHEP::deg);
233 G4LogicalVolume* innerWallTube =
new G4LogicalVolume(innerWallTubeShape, medWall,
"logical" + wallName, 0, 0, 0);
235 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (length + wallZbwd)*CLHEP::cm), innerWallTube,
"physical" + wallName,
248 for (uint iSLayer = 0; iSLayer < nSLayer; ++iSLayer) {
252 double rmin_sensitive_left, rmax_sensitive_left;
253 double rmin_sensitive_middle, rmax_sensitive_middle;
254 double rmin_sensitive_right, rmax_sensitive_right;
255 double zback_sensitive_left, zfor_sensitive_left;
256 double zback_sensitive_middle, zfor_sensitive_middle;
257 double zback_sensitive_right, zfor_sensitive_right;
260 const auto& epLayerBwd = endplate.getEndPlateLayer(1);
261 const auto& epLayerFwd = endplate.getEndPlateLayer((nEPLayer / 2) + 1);
265 rmin_sensitive_left = epLayerBwd.getRmax();
266 rmax_sensitive_left = fieldLayer.
getR();
267 zback_sensitive_left = senseLayer.getZbwd();
268 zfor_sensitive_left = epLayerBwd.getZfwd();
270 rmin_sensitive_middle = (geo.
getInnerWall(0)).getRmax();
271 rmax_sensitive_middle = fieldLayer.getR();
272 zback_sensitive_middle = epLayerBwd.getZfwd();
273 zfor_sensitive_middle = epLayerFwd.getZbwd();
275 rmin_sensitive_right = epLayerFwd.getRmax();
276 rmax_sensitive_right = fieldLayer.getR();
277 zback_sensitive_right = epLayerFwd.getZbwd();
278 zfor_sensitive_right = senseLayer.getZfwd();
279 }
else if (iSLayer >= 1 && iSLayer <= 6) {
280 const auto& epLayerBwd = endplate.getEndPlateLayer(1);
281 const auto& epLayerFwd = endplate.getEndPlateLayer((nEPLayer / 2) + 1);
286 rmin_sensitive_left = epLayerBwd.getRmax();
287 rmax_sensitive_left = fieldLayerOut.
getR();
288 zback_sensitive_left = senseLayer.getZbwd();
289 zfor_sensitive_left = epLayerBwd.getZfwd();
291 rmin_sensitive_middle = fieldLayerIn.getR();
292 rmax_sensitive_middle = fieldLayerOut.getR();
293 zback_sensitive_middle = epLayerBwd.getZfwd();
294 zfor_sensitive_middle = epLayerFwd.getZbwd();
296 rmin_sensitive_right = epLayerFwd.getRmax();
297 rmax_sensitive_right = fieldLayerOut.getR();
298 zback_sensitive_right = epLayerFwd.getZbwd();
299 zfor_sensitive_right = senseLayer.getZfwd();
300 }
else if (iSLayer >= 7 && iSLayer <= 10) {
301 const auto& epLayerBwd = endplate.getEndPlateLayer(1);
302 const auto& epLayerFwd = endplate.getEndPlateLayer(nEPLayer / 2);
307 rmin_sensitive_left = epLayerBwd.getRmax();
308 rmax_sensitive_left = fieldLayerOut.
getR();
309 zback_sensitive_left = senseLayer.getZbwd();
310 zfor_sensitive_left = epLayerBwd.getZfwd();
312 rmin_sensitive_middle = fieldLayerIn.getR();
313 rmax_sensitive_middle = fieldLayerOut.getR();
314 zback_sensitive_middle = epLayerBwd.getZfwd();
315 zfor_sensitive_middle = epLayerFwd.getZbwd();
317 rmin_sensitive_right = epLayerFwd.getRmax();
318 rmax_sensitive_right = fieldLayerOut.getR();
319 zback_sensitive_right = epLayerFwd.getZbwd();
320 zfor_sensitive_right = senseLayer.getZfwd();
321 }
else if (iSLayer >= 11 && iSLayer < 47) {
322 const auto& epLayerBwd = endplate.getEndPlateLayer(0);
323 const auto& epLayerFwd = endplate.getEndPlateLayer(nEPLayer / 2);
328 rmin_sensitive_left = epLayerBwd.getRmax();
329 rmax_sensitive_left = fieldLayerOut.
getR();
330 zback_sensitive_left = senseLayer.getZbwd();
331 zfor_sensitive_left = epLayerBwd.getZfwd();
333 rmin_sensitive_middle = fieldLayerIn.getR();
334 rmax_sensitive_middle = fieldLayerOut.getR();
335 zback_sensitive_middle = epLayerBwd.getZfwd();
336 zfor_sensitive_middle = epLayerFwd.getZbwd();
338 rmin_sensitive_right = epLayerFwd.getRmax();
339 rmax_sensitive_right = fieldLayerOut.getR();
340 zback_sensitive_right = epLayerFwd.getZbwd();
341 zfor_sensitive_right = senseLayer.getZfwd();
343 }
else if (iSLayer == 47) {
345 const auto& epLayerBwdIn = endplate.getEndPlateLayer(0);
346 const auto& epLayerBwdOut = endplate.getEndPlateLayer((nEPLayer / 2) - 1);
347 const auto& epLayerFwdIn = endplate.getEndPlateLayer(nEPLayer / 2);
348 const auto& epLayerFwdOut = endplate.getEndPlateLayer(nEPLayer - 1);
351 int iSLayerMinus1 = iSLayer - 1;
353 rmin_sensitive_left = epLayerBwdIn.getRmax();
354 rmax_sensitive_left = epLayerBwdOut.getRmax();
355 zback_sensitive_left = senseLayer.
getZbwd();
356 zfor_sensitive_left = epLayerBwdIn.getZfwd();
358 rmin_sensitive_middle = fieldLayerIn.getR();
359 rmax_sensitive_middle = (geo.
getOuterWall(0)).getRmin();
360 zback_sensitive_middle = epLayerBwdIn.getZfwd();
361 zfor_sensitive_middle = epLayerFwdIn.getZbwd();
363 rmin_sensitive_right = epLayerFwdIn.getRmax();
364 rmax_sensitive_right = epLayerFwdOut.getRmax();
365 zback_sensitive_right = epLayerFwdIn.getZbwd();
366 zfor_sensitive_right = senseLayer.getZfwd();
369 B2ERROR(
"Undefined sensitive layer : " << iSLayer);
375 if ((zfor_sensitive_left - zback_sensitive_left) > length_feedthrough) {
392 G4Tubs* leftTubeShape =
new G4Tubs((format(
"solidCDCLayer_%1%_leftTube") % iSLayer).str().c_str(), rmin_sensitive_left * CLHEP::cm,
393 rmax_sensitive_left * CLHEP::cm, length_feedthrough * CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
394 G4LogicalVolume* leftTube =
new G4LogicalVolume(leftTubeShape, cdcMed,
395 (format(
"logicalCDCLayer_%1%_leftTube") % iSLayer).str().c_str(), 0, 0, 0);
396 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zback_sensitive_left + length_feedthrough / 2.0)*CLHEP::cm), leftTube,
397 (format(
"physicalCDCLayer_%1%_leftTube") % iSLayer).str().c_str(),
m_logicalCDC,
false, iSLayer);
399 G4Tubs* leftSensitiveTubeShape =
new G4Tubs((format(
"solidSD_CDCLayer_%1%_left") % iSLayer).str().c_str(),
400 rmin_sensitive_left * CLHEP::cm, rmax_sensitive_left * CLHEP::cm,
401 (zfor_sensitive_left - zback_sensitive_left - length_feedthrough)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
402 G4LogicalVolume* leftSensitiveTube =
new G4LogicalVolume(leftSensitiveTubeShape, cdcMed,
403 (format(
"logicalSD_CDCLayer_%1%_left") % iSLayer).str().c_str(), 0, 0, 0);
404 leftSensitiveTube->SetSensitiveDetector(
m_sensitive);
405 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfor_sensitive_left + zback_sensitive_left + length_feedthrough)*CLHEP::cm / 2.0),
406 leftSensitiveTube, (format(
"physicalSD_CDCLayer_%1%_left") % iSLayer).str().c_str(),
m_logicalCDC,
false, iSLayer);
424 G4Tubs* leftTubeShape =
new G4Tubs((format(
"solidCDCLayer_%1%_leftTube") % iSLayer).str().c_str(), rmin_sensitive_left * CLHEP::cm,
425 rmax_sensitive_left * CLHEP::cm, (zfor_sensitive_left - zback_sensitive_left)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
426 G4LogicalVolume* leftTube =
new G4LogicalVolume(leftTubeShape, cdcMed,
427 (format(
"logicalCDCLayer_%1%_leftTube") % iSLayer).str().c_str(), 0, 0, 0);
428 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfor_sensitive_left + zback_sensitive_left)*CLHEP::cm / 2.0), leftTube,
429 (format(
"physicalCDCLayer_%1%_leftTube") % iSLayer).str().c_str(),
m_logicalCDC,
false, iSLayer);
433 G4Tubs* leftMidTubeShape =
new G4Tubs((format(
"solidCDCLayer_%1%_leftMidTube") % iSLayer).str().c_str(),
434 rmin_sensitive_middle * CLHEP::cm, rmax_sensitive_middle * CLHEP::cm,
435 (length_feedthrough - zfor_sensitive_left + zback_sensitive_left)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
436 G4LogicalVolume* leftMidTube =
new G4LogicalVolume(leftMidTubeShape, cdcMed,
437 (format(
"logicalCDCLayer_%1%_leftMidTube") % iSLayer).str().c_str(), 0, 0, 0);
439 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (length_feedthrough + zfor_sensitive_left + zback_sensitive_left)*CLHEP::cm / 2.0),
440 leftMidTube, (format(
"physicalCDCLayer_%1%_leftMidTube") % iSLayer).str().c_str(),
m_logicalCDC,
false, iSLayer);
443 zback_sensitive_middle = length_feedthrough + zback_sensitive_left;
447 if ((zfor_sensitive_right - zback_sensitive_right) > length_feedthrough) {
464 G4Tubs* rightTubeShape =
new G4Tubs((format(
"solidCDCLayer_%1%_rightTube") % iSLayer).str().c_str(),
465 rmin_sensitive_right * CLHEP::cm, rmax_sensitive_right * CLHEP::cm, length_feedthrough * CLHEP::cm / 2.0, 0 * CLHEP::deg,
467 G4LogicalVolume* rightTube =
new G4LogicalVolume(rightTubeShape, cdcMed,
468 (format(
"logicalCDCLayer_%1%_rightTube") % iSLayer).str().c_str(), 0, 0, 0);
470 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfor_sensitive_right - length_feedthrough / 2.0)*CLHEP::cm), rightTube,
471 (format(
"physicalCDCLayer_%1%_rightTube") % iSLayer).str().c_str(),
m_logicalCDC,
false, iSLayer);
475 G4Tubs* rightSensitiveTubeShape =
new G4Tubs((format(
"solidSD_CDCLayer_%1%_right") % iSLayer).str().c_str(),
476 rmin_sensitive_right * CLHEP::cm, rmax_sensitive_right * CLHEP::cm,
477 (zfor_sensitive_right - zback_sensitive_right - length_feedthrough)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
478 G4LogicalVolume* rightSensitiveTube =
new G4LogicalVolume(rightSensitiveTubeShape, cdcMed,
479 (format(
"logicalSD_CDCLayer_%1%_right") % iSLayer).str().c_str(), 0, 0, 0);
480 rightSensitiveTube->SetSensitiveDetector(
m_sensitive);
482 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfor_sensitive_right + zback_sensitive_right - length_feedthrough)*CLHEP::cm / 2.0),
483 rightSensitiveTube, (format(
"physicalSD_CDCLayer_%1%_right") % iSLayer).str().c_str(),
m_logicalCDC,
false, iSLayer);
502 G4Tubs* rightTubeShape =
new G4Tubs((format(
"solidCDCLayer_%1%_rightTube") % iSLayer).str().c_str(),
503 rmin_sensitive_right * CLHEP::cm, rmax_sensitive_right * CLHEP::cm, (zfor_sensitive_right - zback_sensitive_right)*CLHEP::cm / 2.0,
504 0 * CLHEP::deg, 360.*CLHEP::deg);
505 G4LogicalVolume* rightTube =
new G4LogicalVolume(rightTubeShape, cdcMed,
506 (format(
"logicalCDCLayer_%1%_rightTube") % iSLayer).str().c_str(), 0, 0, 0);
508 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfor_sensitive_right + zback_sensitive_right)*CLHEP::cm / 2.0), rightTube,
509 (format(
"physicalCDCLayer_%1%_rightTube") % iSLayer).str().c_str(),
m_logicalCDC,
false, iSLayer);
513 G4Tubs* rightMidTubeShape =
new G4Tubs((format(
"solidCDCLayer_%1%_rightMidTube") % iSLayer).str().c_str(),
514 rmin_sensitive_middle * CLHEP::cm, rmax_sensitive_middle * CLHEP::cm,
515 (length_feedthrough - zfor_sensitive_right + zback_sensitive_right)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
516 G4LogicalVolume* rightMidTube =
new G4LogicalVolume(rightMidTubeShape, cdcMed,
517 (format(
"logicalCDCLayer_%1%_rightMidTube") % iSLayer).str().c_str(), 0, 0, 0);
518 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zback_sensitive_right - length_feedthrough + zfor_sensitive_right)*CLHEP::cm / 2.0),
519 rightMidTube, (format(
"physicalCDCLayer_%1%_rightMidTube") % iSLayer).str().c_str(),
m_logicalCDC,
false, iSLayer);
522 zfor_sensitive_middle = zfor_sensitive_right - length_feedthrough;
527 G4Tubs* middleSensitiveTubeShape =
new G4Tubs((format(
"solidSD_CDCLayer_%1%_middle") % iSLayer).str().c_str(),
528 rmin_sensitive_middle * CLHEP::cm, rmax_sensitive_middle * CLHEP::cm,
529 (zfor_sensitive_middle - zback_sensitive_middle)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
530 G4LogicalVolume* middleSensitiveTube =
new G4LogicalVolume(middleSensitiveTubeShape, cdcMedGas,
531 (format(
"logicalSD_CDCLayer_%1%_middle") % iSLayer).str().c_str(), 0, 0, 0);
534 G4UserLimits* uLimits =
new G4UserLimits(8.5 * CLHEP::cm);
536 middleSensitiveTube->SetUserLimits(uLimits);
537 middleSensitiveTube->SetSensitiveDetector(
m_sensitive);
539 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfor_sensitive_middle + zback_sensitive_middle)*CLHEP::cm / 2.0), middleSensitiveTube,
540 (format(
"physicalSD_CDCLayer_%1%_middle") % iSLayer).str().c_str(),
m_logicalCDC,
false, iSLayer);
544 G4String sName =
"sWire";
549 G4double tAtZ0 = -wb0.
Z() / (wf0.
Z() - wb0.
Z());
552 const G4double epsl = 25.e-4;
553 G4double reductionBwd = (zback_sensitive_middle + epsl) / wb0.
Z();
555 wb0 = reductionBwd * (wb0 - wAtZ0) + wAtZ0;
557 G4double reductionFwd = (zfor_sensitive_middle - epsl) / wf0.
Z();
558 wf0 = reductionFwd * (wf0 - wAtZ0) + wAtZ0;
560 const G4double wireHalfLength = 0.5 * (wf0 - wb0).Mag() * CLHEP::cm;
563 G4Tubs* middleSensitiveSwireShape =
new G4Tubs(sName, 0., sWireRadius, wireHalfLength, 0., 360. * CLHEP::deg);
564 G4LogicalVolume* middleSensitiveSwire =
new G4LogicalVolume(middleSensitiveSwireShape, medTungsten, sName);
568 G4String fName =
"fWire";
570 G4Tubs* middleSensitiveFwireShape =
new G4Tubs(fName, 0., fWireRadius, wireHalfLength, 0., 360. * CLHEP::deg);
571 G4LogicalVolume* middleSensitiveFwire =
new G4LogicalVolume(middleSensitiveFwireShape, medAluminum, fName);
578 const G4double dphi = M_PI / nCells;
581 for (
int ic = 0; ic < nCells; ++ic) {
585 G4double tAtZ02 = -wb.Z() / (wf.
Z() - wb.Z());
587 G4double reductionBwd2 = (zback_sensitive_middle + epsl) / wb.Z();
588 wb = reductionBwd2 * (wb - wAtZ02) + wAtZ02;
589 G4double reductionFwd2 = (zfor_sensitive_middle - epsl) / wf.
Z();
590 wf = reductionFwd2 * (wf - wAtZ02) + wAtZ02;
592 G4double thetaYZ = -asin((wf - wb).Y() / (wf - wb).Mag());
594 B2Vector3D fMinusBInZX((wf - wb).X(), 0., (wf - wb).Z());
595 G4double thetaZX = asin((unitZ.
Cross(fMinusBInZX)).Y() / fMinusBInZX.
Mag());
596 G4RotationMatrix rotM;
598 rotM.rotateX(thetaYZ * CLHEP::rad);
599 rotM.rotateY(thetaZX * CLHEP::rad);
601 G4ThreeVector xyz(0.5 * (wb.X() + wf.
X()) * CLHEP::cm,
602 0.5 * (wb.Y() + wf.
Y()) * CLHEP::cm, 0.);
606 new G4PVPlacement(G4Transform3D(rotM, xyz), middleSensitiveSwire, sName, middleSensitiveTube,
false, ic);
610 G4double rF = rmax_sensitive_middle - 0.5 * diameter;
612 G4double phi = atan2(wbF.
Y(), wbF.
X());
613 wbF.
SetX(rF * cos(phi));
614 wbF.
SetY(rF * sin(phi));
617 rF = rmax_sensitive_middle - 0.5 * diameter;
618 phi = atan2(wfF.
Y(), wfF.
X());
619 wfF.
SetX(rF * cos(phi));
620 wfF.
SetY(rF * sin(phi));
622 thetaYZ = -asin((wfF - wbF).Y() / (wfF - wbF).Mag());
624 fMinusBInZX = wfF - wbF;
625 fMinusBInZX.
SetY(0.);
626 thetaZX = asin((unitZ.
Cross(fMinusBInZX)).Y() / fMinusBInZX.
Mag());
628 G4RotationMatrix rotM1;
629 rotM1.rotateX(thetaYZ * CLHEP::rad);
630 rotM1.rotateY(thetaZX * CLHEP::rad);
632 xyz.setX(0.5 * (wbF.
X() + wfF.
X()) * CLHEP::cm);
633 xyz.setY(0.5 * (wbF.
Y() + wfF.
Y()) * CLHEP::cm);
635 if (iSLayer != nSLayer - 1) {
637 new G4PVPlacement(G4Transform3D(rotM1, xyz), middleSensitiveFwire, fName, middleSensitiveTube,
false, ic);
643 phi = atan2(wbF.
Y(), wbF.
X());
644 wbF.
SetX(rF * cos(phi + dphi));
645 wbF.
SetY(rF * sin(phi + dphi));
649 phi = atan2(wfF.
Y(), wfF.
X());
650 wfF.
SetX(rF * cos(phi + dphi));
651 wfF.
SetY(rF * sin(phi + dphi));
653 thetaYZ = -asin((wfF - wbF).Y() / (wfF - wbF).Mag());
655 fMinusBInZX = wfF - wbF;
656 fMinusBInZX.
SetY(0.);
657 thetaZX = asin((unitZ.
Cross(fMinusBInZX)).Y() / fMinusBInZX.
Mag());
659 G4RotationMatrix rotM2;
660 rotM2.rotateX(thetaYZ * CLHEP::rad);
661 rotM2.rotateY(thetaZX * CLHEP::rad);
663 xyz.setX(0.5 * (wbF.
X() + wfF.
X()) * CLHEP::cm);
664 xyz.setY(0.5 * (wbF.
Y() + wfF.
Y()) * CLHEP::cm);
667 new G4PVPlacement(G4Transform3D(rotM2, xyz), middleSensitiveFwire, fName, middleSensitiveTube,
false, ic + nCells);
671 rF = rmax_sensitive_middle - 0.5 * diameter;
672 phi = atan2(wbF.
Y(), wbF.
X());
673 wbF.
SetX(rF * cos(phi + dphi));
674 wbF.
SetY(rF * sin(phi + dphi));
677 rF = rmax_sensitive_middle - 0.5 * diameter;
678 phi = atan2(wfF.
Y(), wfF.
X());
679 wfF.
SetX(rF * cos(phi + dphi));
680 wfF.
SetY(rF * sin(phi + dphi));
682 thetaYZ = -asin((wfF - wbF).Y() / (wfF - wbF).Mag());
684 fMinusBInZX = wfF - wbF;
685 fMinusBInZX.
SetY(0.);
686 thetaZX = asin((unitZ.
Cross(fMinusBInZX)).Y() / fMinusBInZX.
Mag());
688 G4RotationMatrix rotM3;
689 rotM3.rotateX(thetaYZ * CLHEP::rad);
690 rotM3.rotateY(thetaZX * CLHEP::rad);
692 xyz.setX(0.5 * (wbF.
X() + wfF.
X()) * CLHEP::cm);
693 xyz.setY(0.5 * (wbF.
Y() + wfF.
Y()) * CLHEP::cm);
695 if (iSLayer != nSLayer - 1) {
696 new G4PVPlacement(G4Transform3D(rotM3, xyz), middleSensitiveFwire, fName, middleSensitiveTube,
false, ic + 2 * nCells);
706 m_VisAttributes.push_back(
new G4VisAttributes(
true, G4Colour(1., 1., 0.)));
708 for (
const auto& epLayer : endplate.getEndPlateLayers()) {
709 const int iEPLayer = epLayer.getILayer();
710 const string name = epLayer.getName();
711 const double rmin = epLayer.getRmin();
712 const double rmax = epLayer.getRmax();
713 const double zbwd = epLayer.getZbwd();
714 const double zfwd = epLayer.getZfwd();
715 const double length = (zfwd - zbwd) / 2.0;
717 G4Tubs* tube =
new G4Tubs(
"solidCDCEndplate" + name, rmin * CLHEP::cm,
718 rmax * CLHEP::cm, length * CLHEP::cm, 0 * CLHEP::deg, 360.*CLHEP::deg);
719 G4LogicalVolume* logical =
new G4LogicalVolume(tube,
Materials::get(
"G4_Al"),
720 "logicalCDCEndplate" + name, 0, 0);
722 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfwd + zbwd)*CLHEP::cm / 2.0), logical,
723 "physicalCDCEndplate" + name,
m_logicalCDC,
false, iEPLayer);
732 const int iEB = frontend.getId();
733 const double ebInnerR = frontend.getRmin();
734 const double ebOuterR = frontend.getRmax();
735 const double ebBZ = frontend.getZbwd();
736 const double ebFZ = frontend.getZfwd();
738 G4Tubs* ebTubeShape =
new G4Tubs((format(
"solidSD_ElectronicsBoard_Layer%1%") % iEB).str().c_str(), ebInnerR * CLHEP::cm,
739 ebOuterR * CLHEP::cm, (ebFZ - ebBZ)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
741 G4LogicalVolume* ebTube =
new G4LogicalVolume(ebTubeShape, medNEMA_G10_Plate,
742 (format(
"logicalSD_ElectronicsBoard_Layer%1%") % iEB).str().c_str(), 0, 0, 0);
746 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (ebFZ + ebBZ)*CLHEP::cm / 2.0), ebTube,
747 (format(
"physicalSD_ElectronicsBoard_Layer%1%") % iEB).str().c_str(),
m_logicalCDC,
false, iEB);
768 for (
const auto& rib : geo.
getRibs()) {
770 const int id = rib.getId();
771 const double length = rib.getLength();
772 const double width = rib.getWidth();
773 const double thick = rib.getThick();
774 const double rotx = rib.getRotX();
775 const double roty = rib.getRotY();
776 const double rotz = rib.getRotZ();
777 const double x = rib.getX();
778 const double y = rib.getY();
779 const double z = rib.getZ();
780 const int offset = rib.getOffset();
781 const int ndiv = rib.getNDiv();
783 const string solidName =
"solidRib" + to_string(
id);
784 const string logicalName =
"logicalRib" + to_string(
id);
785 G4Box* boxShape =
new G4Box(solidName, 0.5 * length * CLHEP::cm,
786 0.5 * width * CLHEP::cm,
787 0.5 * thick * CLHEP::cm);
789 const double rmax = 0.5 * length;
790 const double rmin = max((rmax - thick), 0.);
791 G4Tubs* tubeShape =
new G4Tubs(solidName,
794 0.5 * width * CLHEP::cm,
801 G4LogicalVolume* logicalV =
new G4LogicalVolume(boxShape, medAluminum, logicalName, 0, 0, 0);
802 if (
id > 39 &&
id < 78)
803 logicalV =
new G4LogicalVolume(boxShape, medCopper, logicalName, 0, 0, 0);
804 if ((
id > 77 &&
id < 94) || (
id > 131 &&
id < 146))
805 logicalV =
new G4LogicalVolume(boxShape, medNEMA_G10_Plate, logicalName, 0, 0, 0);
806 if (
id > 93 &&
id < 110)
807 logicalV =
new G4LogicalVolume(tubeShape, medCopper, logicalName, 0, 0, 0);
808 if (
id > 109 &&
id < 126)
809 logicalV =
new G4LogicalVolume(tubeShape, medH2O, logicalName, 0, 0, 0);
810 if (
id > 127 &&
id < 132)
811 logicalV =
new G4LogicalVolume(boxShape, medHV, logicalName, 0, 0, 0);
821 const double phi = 360.0 / ndiv;
823 G4RotationMatrix rot = G4RotationMatrix();
825 if (
id > 93 &&
id < 126) dz = 0;
827 G4ThreeVector arm(x * CLHEP::cm, y * CLHEP::cm, z * CLHEP::cm - dz * CLHEP::cm / 2.0);
832 rot.rotateZ(0.5 * phi * CLHEP::deg);
833 arm.rotateZ(0.5 * phi * CLHEP::deg);
835 for (
int i = 0; i < ndiv; ++i) {
836 const string physicalName =
"physicalRib_" + to_string(
id) +
" " + to_string(i);
837 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
839 rot.rotateZ(phi * CLHEP::deg);
840 arm.rotateZ(phi * CLHEP::deg);
848 for (
const auto& rib2 : geo.
getRib2s()) {
850 const int id = rib2.getId();
851 const double length = rib2.getLength();
852 const double width = rib2.getWidth();
853 const double thick = rib2.getThick();
854 const double width2 = rib2.getWidth2();
855 const double thick2 = rib2.getThick2();
856 const double rotx = rib2.getRotX();
857 const double roty = rib2.getRotY();
858 const double rotz = rib2.getRotZ();
859 const double x = rib2.getX();
860 const double y = rib2.getY();
861 const double z = rib2.getZ();
862 const int ndiv = rib2.getNDiv();
864 const string solidName =
"solidRib2" + to_string(
id);
865 const string logicalName =
"logicalRib2" + to_string(
id);
866 G4Trd* trdShape =
new G4Trd(solidName,
867 0.5 * thick * CLHEP::cm,
868 0.5 * thick2 * CLHEP::cm,
869 0.5 * width * CLHEP::cm,
870 0.5 * width2 * CLHEP::cm,
871 0.5 * length * CLHEP::cm);
873 G4LogicalVolume* logicalV =
new G4LogicalVolume(trdShape, medAluminum, logicalName, 0, 0, 0);
876 logicalV =
new G4LogicalVolume(trdShape, medCopper, logicalName, 0, 0, 0);
880 const double phi = 360.0 / ndiv;
882 G4RotationMatrix rot = G4RotationMatrix();
883 G4ThreeVector arm(x * CLHEP::cm, y * CLHEP::cm, z * CLHEP::cm - thick * CLHEP::cm / 2.0);
888 for (
int i = 0; i < ndiv; ++i) {
889 const string physicalName =
"physicalRib2_" + to_string(
id) +
" " + to_string(i);
890 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
892 rot.rotateZ(phi * CLHEP::deg);
893 arm.rotateZ(phi * CLHEP::deg);
901 for (
const auto& rib3 : geo.
getRib3s()) {
903 const int id = rib3.getId();
904 const double length = rib3.getLength();
905 const double width = rib3.getWidth();
906 const double thick = rib3.getThick();
907 const double r = rib3.getR();
908 const double x = rib3.getX();
909 const double y = rib3.getY();
910 const double z = rib3.getZ();
911 const double rx = rib3.getRx();
912 const double ry = rib3.getRy();
913 const double rz = rib3.getRz();
914 const int offset = rib3.getOffset();
915 const int ndiv = rib3.getNDiv();
917 const string logicalName =
"logicalRib3" + to_string(
id);
918 G4VSolid* boxShape =
new G4Box(
"Block",
919 0.5 * length * CLHEP::cm,
920 0.5 * width * CLHEP::cm,
921 0.5 * thick * CLHEP::cm);
922 G4VSolid* tubeShape =
new G4Tubs(
"Hole",
929 G4RotationMatrix rotsub = G4RotationMatrix();
930 rotsub.rotateX(90. * CLHEP::deg);
931 G4ThreeVector trnsub(rx * CLHEP::cm - x * CLHEP::cm, ry * CLHEP::cm - y * CLHEP::cm,
932 rz * CLHEP::cm - z * CLHEP::cm + 0.5 * thick * CLHEP::cm);
933 G4VSolid* coolingBlock =
new G4SubtractionSolid(
"Block-Hole",
936 G4Transform3D(rotsub,
939 G4LogicalVolume* logicalV =
new G4LogicalVolume(coolingBlock, medCopper, logicalName, 0, 0, 0);
943 const double phi = 360.0 / ndiv;
945 G4RotationMatrix rot = G4RotationMatrix();
946 G4ThreeVector arm(x * CLHEP::cm, y * CLHEP::cm, z * CLHEP::cm - thick * CLHEP::cm / 2.0);
949 rot.rotateZ(0.5 * phi * CLHEP::deg);
950 arm.rotateZ(0.5 * phi * CLHEP::deg);
952 for (
int i = 0; i < ndiv; ++i) {
953 const string physicalName =
"physicalRib3_" + to_string(
id) +
" " + to_string(i);
954 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
956 rot.rotateZ(phi * CLHEP::deg);
957 arm.rotateZ(phi * CLHEP::deg);
965 for (
const auto& rib4 : geo.
getRib4s()) {
967 const int id = rib4.getId();
968 const double length = rib4.getLength();
969 const double width = rib4.getWidth();
970 const double thick = rib4.getThick();
971 const double length2 = rib4.getLength2();
972 const double width2 = rib4.getWidth2();
973 const double thick2 = rib4.getThick2();
974 const double x = rib4.getX();
975 const double y = rib4.getY();
976 const double z = rib4.getZ();
977 const double x2 = rib4.getX2();
978 const double y2 = rib4.getY2();
979 const double z2 = rib4.getZ2();
980 const int offset = rib4.getOffset();
981 const int ndiv = rib4.getNDiv();
983 const string logicalName =
"logicalRib4" + to_string(
id);
984 G4VSolid* baseShape =
new G4Box(
"Base",
985 0.5 * length * CLHEP::cm,
986 0.5 * width * CLHEP::cm,
987 0.5 * thick * CLHEP::cm);
988 G4VSolid* sqShape =
new G4Box(
"Sq",
989 0.5 * length2 * CLHEP::cm,
990 0.5 * width2 * CLHEP::cm,
991 0.5 * thick2 * CLHEP::cm);
993 G4RotationMatrix rotsub = G4RotationMatrix();
994 double dzc = (z2 - thick2 / 2.) - (z - thick / 2.);
995 G4ThreeVector trnsub(x2 * CLHEP::cm - x * CLHEP::cm,
996 y2 * CLHEP::cm - y * CLHEP::cm,
998 G4VSolid* sqHoleBase =
new G4SubtractionSolid(
"Box-Sq",
1001 G4Transform3D(rotsub,
1005 G4LogicalVolume* logicalV =
new G4LogicalVolume(sqHoleBase, medCopper, logicalName, 0, 0, 0);
1007 logicalV =
new G4LogicalVolume(sqHoleBase, medNEMA_G10_Plate, logicalName, 0, 0, 0);
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,
1026 rot.rotateZ(phi * CLHEP::deg);
1027 arm.rotateZ(phi * CLHEP::deg);
1034 for (
const auto& rib5 : geo.
getRib5s()) {
1036 const int id = rib5.getId();
1037 const double dr = rib5.getDr();
1038 const double dz = rib5.getDz();
1039 const double width = rib5.getWidth();
1040 const double thick = rib5.getThick();
1041 const double rin = rib5.getRin();
1042 const double x = rib5.getX();
1043 const double y = rib5.getY();
1044 const double z = rib5.getZ();
1045 const double rotx = rib5.getRotx();
1046 const double roty = rib5.getRoty();
1047 const double rotz = rib5.getRotz();
1048 const int offset = rib5.getOffset();
1049 const int ndiv = rib5.getNDiv();
1051 const string solidName =
"solidRib5" + to_string(
id);
1052 const string logicalName =
"logicalRib5" + to_string(
id);
1054 const double rmax = rin + thick;
1055 const double rmin = rin;
1056 const double dphi = 2. * atan2(dz, dr);
1057 const double ddphi = thick * tan(dphi) / rin;
1058 const double ddphi2 = width / 2. * width / 2. / (x + dr) / rin;
1059 const double cphi = dphi - ddphi - ddphi2;
1060 G4Tubs* tubeShape =
new G4Tubs(solidName,
1063 0.5 * width * CLHEP::cm,
1067 G4LogicalVolume* logicalV =
new G4LogicalVolume(tubeShape, medAluminum, logicalName, 0, 0, 0);
1071 const double phi = 360.0 / ndiv;
1073 G4RotationMatrix rot = G4RotationMatrix();
1076 G4ThreeVector arm(x * CLHEP::cm, y * CLHEP::cm, z * CLHEP::cm - rin * CLHEP::cm - thick * CLHEP::cm);
1081 rot.rotateZ(0.5 * phi * CLHEP::deg);
1082 arm.rotateZ(0.5 * phi * CLHEP::deg);
1084 for (
int i = 0; i < ndiv; ++i) {
1085 const string physicalName =
"physicalRib5_" + to_string(
id) +
" " + to_string(i);
1086 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
1088 rot.rotateZ(phi * CLHEP::deg);
1089 arm.rotateZ(phi * CLHEP::deg);
1107 G4Material* boratedpoly05 =
new G4Material(
"BoratedPoly05", 1.06 * CLHEP::g / CLHEP::cm3, 2);
1108 boratedpoly05->AddMaterial(elB, 0.05);
1109 boratedpoly05->AddMaterial(C2H4, 0.95);
1111 G4Material* boratedpoly30 =
new G4Material(
"BoratedPoly30", 1.19 * CLHEP::g / CLHEP::cm3, 2);
1112 boratedpoly30->AddMaterial(elB, 0.30);
1113 boratedpoly30->AddMaterial(C2H4, 0.70);
1115 G4Material* shieldMat = C2H4;
1117 const int nShields = content.getNumberNodes(
"Shields/Shield");
1119 for (
int iShield = 0; iShield < nShields; ++iShield) {
1120 GearDir shieldContent(content);
1121 shieldContent.
append((format(
"/Shields/Shield[%1%]/") % (iShield + 1)).str());
1122 const string sShieldID = shieldContent.
getString(
"@id");
1123 const int shieldID = atoi(sShieldID.c_str());
1125 const double shieldInnerR1 = shieldContent.
getLength(
"InnerR1");
1126 const double shieldInnerR2 = shieldContent.
getLength(
"InnerR2");
1127 const double shieldOuterR1 = shieldContent.
getLength(
"OuterR1");
1128 const double shieldOuterR2 = shieldContent.
getLength(
"OuterR2");
1129 const double shieldThick = shieldContent.
getLength(
"Thickness");
1130 const double shieldPosZ = shieldContent.
getLength(
"PosZ");
1132 G4Cons* shieldConsShape =
new G4Cons((format(
"solidShield%1%") % shieldID).str().c_str(),
1133 shieldInnerR1 * CLHEP::cm, shieldOuterR1 * CLHEP::cm,
1134 shieldInnerR2 * CLHEP::cm, shieldOuterR2 * CLHEP::cm,
1135 shieldThick * CLHEP::cm / 2.0,
1136 0.*CLHEP::deg, 360.*CLHEP::deg);
1138 G4LogicalVolume* shieldCons =
new G4LogicalVolume(shieldConsShape, shieldMat, (format(
"logicalShield%1%") % shieldID).str().c_str(),
1141 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (shieldPosZ - shieldThick / 2.0) * CLHEP::cm), shieldCons,
1142 (format(
"physicalShield%1%") % shieldID).str().c_str(),
m_logicalCDC,
false, 0);
1153 G4Material* shieldMat = C2H4;
1155 for (
const auto& shield : geom.getNeutronShields()) {
1156 const int shieldID = shield.getId();
1157 const double shieldInnerR1 = shield.getRmin1();
1158 const double shieldInnerR2 = shield.getRmin2();
1159 const double shieldOuterR1 = shield.getRmax1();
1160 const double shieldOuterR2 = shield.getRmax2();
1161 const double shieldThick = shield.getThick();
1162 const double shieldPosZ = shield.getZ();
1164 G4Cons* shieldConsShape =
new G4Cons(
"solidShield" + to_string(shieldID),
1165 shieldInnerR1 * CLHEP::cm, shieldOuterR1 * CLHEP::cm,
1166 shieldInnerR2 * CLHEP::cm, shieldOuterR2 * CLHEP::cm,
1167 shieldThick * CLHEP::cm / 2.0,
1168 0.*CLHEP::deg, 360.*CLHEP::deg);
1170 G4LogicalVolume* shieldCons =
new G4LogicalVolume(shieldConsShape, shieldMat,
"logicalShield" + to_string(shieldID),
1173 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (shieldPosZ - shieldThick / 2.0) * CLHEP::cm), shieldCons,
1174 "physicalShield" + to_string(shieldID),
m_logicalCDC,
false, 0);
1182 string Aluminum = content.getString(
"Aluminum");
1185 G4double density = 1.000 * CLHEP::g / CLHEP::cm3;
1186 G4double a = 1.01 * CLHEP::g / CLHEP::mole;
1187 G4Element* elH =
new G4Element(
"Hydrogen",
"H", 1., a);
1188 a = 16.00 * CLHEP::g / CLHEP::mole;
1189 G4Element* elO =
new G4Element(
"Oxygen",
"O", 8., a);
1190 G4Material* medH2O =
new G4Material(
"Water", density, 2);
1191 medH2O->AddElement(elH, 2);
1192 medH2O->AddElement(elO, 1);
1200 m_VisAttributes.push_back(
new G4VisAttributes(
true, G4Colour(0., 1., 0.)));
1201 const int nCover = content.getNumberNodes(
"Covers/Cover");
1202 for (
int iCover = 0; iCover < nCover; ++iCover) {
1203 GearDir coverContent(content);
1204 coverContent.
append((format(
"/Covers/Cover[%1%]/") % (iCover + 1)).str());
1205 const string scoverID = coverContent.
getString(
"@id");
1206 const int coverID = atoi(scoverID.c_str());
1207 const string coverName = coverContent.
getString(
"Name");
1208 const double coverInnerR1 = coverContent.
getLength(
"InnerR1");
1209 const double coverInnerR2 = coverContent.
getLength(
"InnerR2");
1210 const double coverOuterR1 = coverContent.
getLength(
"OuterR1");
1211 const double coverOuterR2 = coverContent.
getLength(
"OuterR2");
1212 const double coverThick = coverContent.
getLength(
"Thickness");
1213 const double coverPosZ = coverContent.
getLength(
"PosZ");
1215 const double rmin1 = coverInnerR1;
1216 const double rmax1 = coverOuterR1;
1217 const double rmin2 = coverInnerR2;
1218 const double rmax2 = coverOuterR2;
1229 if (coverID == 7 || coverID == 10) {
1230 createCone(rmin1, rmax1, rmin2, rmax2, coverThick, coverPosZ, coverID, medAluminum, coverName);
1232 createTube(rmin1, rmax1, coverThick, coverPosZ, coverID, medAluminum, coverName);
1235 if (coverID > 22 && coverID < 29)
1236 createTube(rmin1, rmax1, coverThick, coverPosZ, coverID, medCopper, coverName);
1237 if (coverID > 28 && coverID < 35)
1238 createTorus(rmin1, rmax1, coverThick, coverPosZ, coverID, medCopper, coverName);
1239 if (coverID > 34 && coverID < 41)
1240 createTorus(rmin1, rmax1, coverThick, coverPosZ, coverID, medH2O, coverName);
1241 if (coverID == 45 || coverID == 46)
1242 createTube(rmin1, rmax1, coverThick, coverPosZ, coverID, medLV, coverName);
1243 if (coverID == 47 || coverID == 48)
1244 createTube(rmin1, rmax1, coverThick, coverPosZ, coverID, medFiber, coverName);
1245 if (coverID == 49 || coverID == 50)
1246 createTube(rmin1, rmax1, coverThick, coverPosZ, coverID, medCAT7, coverName);
1247 if (coverID == 51 || coverID == 52)
1248 createTube(rmin1, rmax1, coverThick, coverPosZ, coverID, medTRG, coverName);
1250 createTube(rmin1, rmax1, coverThick, coverPosZ, coverID, medHV, coverName);
1253 const int nCover2 = content.getNumberNodes(
"Covers/Cover2");
1254 for (
int iCover2 = 0; iCover2 < nCover2; ++iCover2) {
1255 GearDir cover2Content(content);
1256 cover2Content.
append((format(
"/Cover2s/Cover2[%1%]/") % (iCover2 + 1)).str());
1257 const string scover2ID = cover2Content.
getString(
"@id");
1258 const int cover2ID = atoi(scover2ID.c_str());
1259 const string cover2Name = cover2Content.
getString(
"Name");
1260 const double cover2InnerR = cover2Content.
getLength(
"InnerR");
1261 const double cover2OuterR = cover2Content.
getLength(
"OuterR");
1262 const double cover2StartPhi = cover2Content.
getLength(
"StartPhi");
1263 const double cover2DeltaPhi = cover2Content.
getLength(
"DeltaPhi");
1264 const double cover2Thick = cover2Content.
getLength(
"Thickness");
1265 const double cover2PosZ = cover2Content.
getLength(
"PosZ");
1268 createTube2(cover2InnerR, cover2OuterR, cover2StartPhi, cover2DeltaPhi, cover2Thick, cover2PosZ, cover2ID, medHV, cover2Name);
1269 if (cover2ID > 10 && cover2ID < 14)
1270 createTube2(cover2InnerR, cover2OuterR, cover2StartPhi, cover2DeltaPhi, cover2Thick, cover2PosZ, cover2ID, medFiber, cover2Name);
1271 if (cover2ID > 13 && cover2ID < 23)
1272 createTube2(cover2InnerR, cover2OuterR, cover2StartPhi, cover2DeltaPhi, cover2Thick, cover2PosZ, cover2ID, medCAT7, cover2Name);
1273 if (cover2ID > 22 && cover2ID < 29)
1274 createTube2(cover2InnerR, cover2OuterR, cover2StartPhi, cover2DeltaPhi, cover2Thick, cover2PosZ, cover2ID, medTRG, cover2Name);
1277 const int nRibs = content.getNumberNodes(
"Covers/Rib");
1278 for (
int iRib = 0; iRib < nRibs; ++iRib) {
1280 ribContent.
append((format(
"/Covers/Rib[%1%]/") % (iRib + 1)).str());
1281 const string sribID = ribContent.
getString(
"@id");
1282 const int ribID = atoi(sribID.c_str());
1284 const double length = ribContent.
getLength(
"Length");
1285 const double width = ribContent.
getLength(
"Width");
1286 const double thick = ribContent.
getLength(
"Thickness");
1287 const double rotX = ribContent.
getLength(
"RotX");
1288 const double rotY = ribContent.
getLength(
"RotY");
1289 const double rotZ = ribContent.
getLength(
"RotZ");
1290 const double cX = ribContent.
getLength(
"PosX");
1291 const double cY = ribContent.
getLength(
"PosY");
1292 const double cZ = ribContent.
getLength(
"PosZ");
1293 const int offset = atoi((ribContent.
getString(
"Offset")).c_str());
1294 const int number = atoi((ribContent.
getString(
"NDiv")).c_str());
1296 const string solidName =
"solidRib" + to_string(ribID);
1297 const string logicalName =
"logicalRib" + to_string(ribID);
1298 G4Box* boxShape =
new G4Box(solidName, 0.5 * length * CLHEP::cm,
1299 0.5 * width * CLHEP::cm,
1300 0.5 * thick * CLHEP::cm);
1301 const double rmax = 0.5 * length;
1302 const double rmin = max((rmax - thick), 0.);
1303 G4Tubs* tubeShape =
new G4Tubs(solidName,
1306 0.5 * width * CLHEP::cm,
1313 G4LogicalVolume* logicalV =
new G4LogicalVolume(boxShape, medAluminum, logicalName, 0, 0, 0);
1314 if (ribID > 39 && ribID < 78)
1315 logicalV =
new G4LogicalVolume(boxShape, medCopper, logicalName, 0, 0, 0);
1316 if ((ribID > 77 && ribID < 94) || (ribID > 131 && ribID < 146))
1317 logicalV =
new G4LogicalVolume(boxShape, medNEMA_G10_Plate, logicalName, 0, 0, 0);
1318 if (ribID > 93 && ribID < 110)
1319 logicalV =
new G4LogicalVolume(tubeShape, medCopper, logicalName, 0, 0, 0);
1320 if (ribID > 109 && ribID < 126)
1321 logicalV =
new G4LogicalVolume(tubeShape, medH2O, logicalName, 0, 0, 0);
1322 if (ribID > 127 && ribID < 132)
1323 logicalV =
new G4LogicalVolume(boxShape, medHV, logicalName, 0, 0, 0);
1333 const double phi = 360.0 / number;
1335 G4RotationMatrix rot = G4RotationMatrix();
1338 if (ribID > 93 && ribID < 126) dz = 0;
1339 G4ThreeVector arm(cX * CLHEP::cm, cY * CLHEP::cm, cZ * CLHEP::cm - dz * CLHEP::cm / 2.0);
1345 rot.rotateZ(0.5 * phi * CLHEP::deg);
1346 arm.rotateZ(0.5 * phi * CLHEP::deg);
1348 for (
int i = 0; i < number; ++i) {
1349 const string physicalName =
"physicalRib_" + to_string(ribID) +
" " + to_string(i);
1350 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
1352 rot.rotateZ(phi * CLHEP::deg);
1353 arm.rotateZ(phi * CLHEP::deg);
1358 const int nRib2s = content.getNumberNodes(
"Covers/Rib2");
1359 for (
int iRib2 = 0; iRib2 < nRib2s; ++iRib2) {
1361 rib2Content.
append((format(
"/Covers/Rib2[%1%]/") % (iRib2 + 1)).str());
1362 const string srib2ID = rib2Content.
getString(
"@id");
1363 const int rib2ID = atoi(srib2ID.c_str());
1365 const double length = rib2Content.
getLength(
"Length");
1366 const double width = rib2Content.
getLength(
"Width");
1367 const double thick = rib2Content.
getLength(
"Thickness");
1368 const double width2 = rib2Content.
getLength(
"Width2");
1369 const double thick2 = rib2Content.
getLength(
"Thickness2");
1370 const double rotX = rib2Content.
getLength(
"RotX");
1371 const double rotY = rib2Content.
getLength(
"RotY");
1372 const double rotZ = rib2Content.
getLength(
"RotZ");
1373 const double cX = rib2Content.
getLength(
"PosX");
1374 const double cY = rib2Content.
getLength(
"PosY");
1375 const double cZ = rib2Content.
getLength(
"PosZ");
1376 const int number = atoi((rib2Content.
getString(
"NDiv")).c_str());
1378 const string solidName =
"solidRib2" + to_string(rib2ID);
1379 const string logicalName =
"logicalRib2" + to_string(rib2ID);
1380 G4Trd* trdShape =
new G4Trd(solidName,
1381 0.5 * thick * CLHEP::cm,
1382 0.5 * thick2 * CLHEP::cm,
1383 0.5 * width * CLHEP::cm,
1384 0.5 * width2 * CLHEP::cm,
1385 0.5 * length * CLHEP::cm);
1387 G4LogicalVolume* logicalV =
new G4LogicalVolume(trdShape, medAluminum, logicalName, 0, 0, 0);
1389 logicalV =
new G4LogicalVolume(trdShape, medCopper, logicalName, 0, 0, 0);
1393 const double phi = 360.0 / number;
1395 G4RotationMatrix rot = G4RotationMatrix();
1396 G4ThreeVector arm(cX * CLHEP::cm, cY * CLHEP::cm, cZ * CLHEP::cm - thick * CLHEP::cm / 2.0);
1401 for (
int i = 0; i < number; ++i) {
1402 const string physicalName =
"physicalRib2_" + to_string(rib2ID) +
" " + to_string(i);
1403 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
1405 rot.rotateZ(phi * CLHEP::deg);
1406 arm.rotateZ(phi * CLHEP::deg);
1411 const int nRib3s = content.getNumberNodes(
"Covers/Rib3");
1412 for (
int iRib3 = 0; iRib3 < nRib3s; ++iRib3) {
1414 rib3Content.
append((format(
"/Covers/Rib3[%1%]/") % (iRib3 + 1)).str());
1415 const string srib3ID = rib3Content.
getString(
"@id");
1416 const int rib3ID = atoi(srib3ID.c_str());
1418 const double length = rib3Content.
getLength(
"Length");
1419 const double width = rib3Content.
getLength(
"Width");
1420 const double thick = rib3Content.
getLength(
"Thickness");
1421 const double r = rib3Content.
getLength(
"HoleR");
1422 const double cX = rib3Content.
getLength(
"PosX");
1423 const double cY = rib3Content.
getLength(
"PosY");
1424 const double cZ = rib3Content.
getLength(
"PosZ");
1425 const double hX = rib3Content.
getLength(
"HoleX");
1426 const double hY = rib3Content.
getLength(
"HoleY");
1427 const double hZ = rib3Content.
getLength(
"HoleZ");
1428 const int offset = atoi((rib3Content.
getString(
"Offset")).c_str());
1429 const int number = atoi((rib3Content.
getString(
"NDiv")).c_str());
1431 const string logicalName =
"logicalRib3" + to_string(rib3ID);
1432 G4VSolid* boxShape =
new G4Box(
"Block",
1433 0.5 * length * CLHEP::cm,
1434 0.5 * width * CLHEP::cm,
1435 0.5 * thick * CLHEP::cm);
1436 G4VSolid* tubeShape =
new G4Tubs(
"Hole",
1442 G4RotationMatrix rotsub = G4RotationMatrix();
1443 G4ThreeVector trnsub(cX * CLHEP::cm - hX * CLHEP::cm, cY * CLHEP::cm - hY * CLHEP::cm,
1444 cZ * CLHEP::cm - hZ * CLHEP::cm + 0.5 * thick * CLHEP::cm);
1445 G4VSolid* coolingBlock =
new G4SubtractionSolid(
"Block-Hole",
1448 G4Transform3D(rotsub,
1451 G4LogicalVolume* logicalV =
new G4LogicalVolume(coolingBlock, medCopper, logicalName, 0, 0, 0);
1455 const double phi = 360.0 / number;
1457 G4RotationMatrix rot = G4RotationMatrix();
1458 G4ThreeVector arm(cX * CLHEP::cm, cY * CLHEP::cm, cZ * CLHEP::cm - thick * CLHEP::cm / 2.0);
1461 rot.rotateZ(0.5 * phi * CLHEP::deg);
1462 arm.rotateZ(0.5 * phi * CLHEP::deg);
1464 for (
int i = 0; i < number; ++i) {
1465 const string physicalName =
"physicalRib3_" + to_string(rib3ID) +
" " + to_string(i);
1466 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
1468 rot.rotateZ(phi * CLHEP::deg);
1469 arm.rotateZ(phi * CLHEP::deg);
1474 const int nRib4s = content.getNumberNodes(
"Covers/Rib4");
1475 for (
int iRib4 = 0; iRib4 < nRib4s; ++iRib4) {
1477 rib4Content.
append((format(
"/Covers/Rib4[%1%]/") % (iRib4 + 1)).str());
1478 const string srib4ID = rib4Content.
getString(
"@id");
1479 const int rib4ID = atoi(srib4ID.c_str());
1481 const double length = rib4Content.
getLength(
"Length");
1482 const double width = rib4Content.
getLength(
"Width");
1483 const double thick = rib4Content.
getLength(
"Thickness");
1484 const double length2 = rib4Content.
getLength(
"Length2");
1485 const double width2 = rib4Content.
getLength(
"Width2");
1486 const double thick2 = rib4Content.
getLength(
"Thickness2");
1487 const double cX = rib4Content.
getLength(
"PosX");
1488 const double cY = rib4Content.
getLength(
"PosY");
1489 const double cZ = rib4Content.
getLength(
"PosZ");
1490 const double hX = rib4Content.
getLength(
"HoleX");
1491 const double hY = rib4Content.
getLength(
"HoleY");
1492 const double hZ = rib4Content.
getLength(
"HoleZ");
1493 const int offset = atoi((rib4Content.
getString(
"Offset")).c_str());
1494 const int number = atoi((rib4Content.
getString(
"NDiv")).c_str());
1496 const string logicalName =
"logicalRib4" + to_string(rib4ID);
1497 G4VSolid* baseShape =
new G4Box(
"Base",
1498 0.5 * length * CLHEP::cm,
1499 0.5 * width * CLHEP::cm,
1500 0.5 * thick * CLHEP::cm);
1501 G4VSolid* sqShape =
new G4Box(
"Sq",
1502 0.5 * length2 * CLHEP::cm,
1503 0.5 * width2 * CLHEP::cm,
1504 0.5 * thick2 * CLHEP::cm);
1505 G4RotationMatrix rotsub = G4RotationMatrix();
1506 double dzc = (hZ - thick2 / 2.) - (cZ - thick / 2.);
1507 G4ThreeVector trnsub(hX * CLHEP::cm - cX * CLHEP::cm,
1508 hY * CLHEP::cm - cY * CLHEP::cm,
1510 G4VSolid* sqHoleBase =
new G4SubtractionSolid(
"Base-Sq",
1513 G4Transform3D(rotsub,
1517 G4LogicalVolume* logicalV =
new G4LogicalVolume(sqHoleBase, medCopper, logicalName, 0, 0, 0);
1519 logicalV =
new G4LogicalVolume(sqHoleBase, medNEMA_G10_Plate, logicalName, 0, 0, 0);
1523 const double phi = 360.0 / number;
1525 G4RotationMatrix rot = G4RotationMatrix();
1526 G4ThreeVector arm(cX * CLHEP::cm, cY * CLHEP::cm, cZ * CLHEP::cm - thick * CLHEP::cm / 2.0);
1529 rot.rotateZ(0.5 * phi * CLHEP::deg);
1530 arm.rotateZ(0.5 * phi * CLHEP::deg);
1532 for (
int i = 0; i < number; ++i) {
1533 const string physicalName =
"physicalRib4_" + to_string(rib4ID) +
" " + to_string(i);
1534 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
1536 rot.rotateZ(phi * CLHEP::deg);
1537 arm.rotateZ(phi * CLHEP::deg);
1542 const int nRib5s = content.getNumberNodes(
"Covers/Rib5");
1543 for (
int iRib5 = 0; iRib5 < nRib5s; ++iRib5) {
1545 rib5Content.
append((format(
"/Covers/Rib5[%1%]/") % (iRib5 + 1)).str());
1546 const string srib5ID = rib5Content.
getString(
"@id");
1547 const int rib5ID = atoi(srib5ID.c_str());
1549 const double dr = rib5Content.
getLength(
"DeltaR");
1550 const double dz = rib5Content.
getLength(
"DeltaZ");
1551 const double width = rib5Content.
getLength(
"Width");
1552 const double thick = rib5Content.
getLength(
"Thickness");
1553 const double rin = rib5Content.
getLength(
"Rin");
1554 const double rotX = rib5Content.
getLength(
"RotX");
1555 const double rotY = rib5Content.
getLength(
"RotY");
1556 const double rotZ = rib5Content.
getLength(
"RotZ");
1557 const double cX = rib5Content.
getLength(
"PosX");
1558 const double cY = rib5Content.
getLength(
"PosY");
1559 const double cZ = rib5Content.
getLength(
"PosZ");
1560 const int offset = atoi((rib5Content.
getString(
"Offset")).c_str());
1561 const int number = atoi((rib5Content.
getString(
"NDiv")).c_str());
1563 const string solidName =
"solidRib5" + to_string(rib5ID);
1564 const string logicalName =
"logicalRib5" + to_string(rib5ID);
1565 const double rmax = rin + thick;
1566 const double rmin = rin;
1567 const double dphi = 2. * atan2(dz, dr);
1568 const double ddphi = thick * tan(dphi) / rin;
1569 const double ddphi2 = width / 2. * width / 2. / (cX + dr) / rin;
1570 const double cphi = dphi - ddphi - ddphi2;
1571 G4Tubs* tubeShape =
new G4Tubs(solidName,
1574 0.5 * width * CLHEP::cm,
1578 G4LogicalVolume* logicalV =
new G4LogicalVolume(tubeShape, medAluminum, logicalName, 0, 0, 0);
1582 const double phi = 360.0 / number;
1584 G4RotationMatrix rot = G4RotationMatrix();
1587 G4ThreeVector arm(cX * CLHEP::cm, cY * CLHEP::cm, cZ * CLHEP::cm - rin * CLHEP::cm - thick * CLHEP::cm);
1593 rot.rotateZ(0.5 * phi * CLHEP::deg);
1594 arm.rotateZ(0.5 * phi * CLHEP::deg);
1596 for (
int i = 0; i < number; ++i) {
1597 const string physicalName =
"physicalRib5_" + to_string(rib5ID) +
" " + to_string(i);
1598 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
1600 rot.rotateZ(phi * CLHEP::deg);
1601 arm.rotateZ(phi * CLHEP::deg);
1611 G4double density = 1.000 * CLHEP::g / CLHEP::cm3;
1612 G4double a = 1.01 * CLHEP::g / CLHEP::mole;
1613 G4Element* elH =
new G4Element(
"Hydrogen",
"H", 1., a);
1614 a = 16.00 * CLHEP::g / CLHEP::mole;
1615 G4Element* elO =
new G4Element(
"Oxygen",
"O", 8., a);
1616 G4Material* medH2O =
new G4Material(
"water", density, 2);
1617 medH2O->AddElement(elH, 2);
1618 medH2O->AddElement(elO, 1);
1626 m_VisAttributes.push_back(
new G4VisAttributes(
true, G4Colour(0., 1., 0.)));
1627 for (
const auto& cover : geom.getCovers()) {
1628 const int coverID = cover.getId();
1629 const string coverName =
"cover" + to_string(coverID);
1630 const double rmin1 = cover.getRmin1();
1631 const double rmin2 = cover.getRmin2();
1632 const double rmax1 = cover.getRmax1();
1633 const double rmax2 = cover.getRmax2();
1634 const double thick = cover.getThick();
1635 const double posZ = cover.getZ();
1644 if (coverID == 7 || coverID == 10) {
1645 createCone(rmin1, rmax1, rmin2, rmax2, thick, posZ, coverID, medAl, coverName);
1647 createTube(rmin1, rmax1, thick, posZ, coverID, medAl, coverName);
1650 if (coverID > 22 && coverID < 29)
1651 createTube(rmin1, rmax1, thick, posZ, coverID, medCu, coverName);
1652 if (coverID > 28 && coverID < 35)
1653 createTorus(rmin1, rmax1, thick, posZ, coverID, medCu, coverName);
1654 if (coverID > 34 && coverID < 41)
1655 createTorus(rmin1, rmax1, thick, posZ, coverID, medH2O, coverName);
1656 if (coverID == 45 || coverID == 46)
1657 createTube(rmin1, rmax1, thick, posZ, coverID, medLV, coverName);
1658 if (coverID == 47 || coverID == 48)
1659 createTube(rmin1, rmax1, thick, posZ, coverID, medFiber, coverName);
1660 if (coverID == 49 || coverID == 50)
1661 createTube(rmin1, rmax1, thick, posZ, coverID, medCAT7, coverName);
1662 if (coverID == 51 || coverID == 52)
1663 createTube(rmin1, rmax1, thick, posZ, coverID, medTRG, coverName);
1665 createTube(rmin1, rmax1, thick, posZ, coverID, medHV, coverName);
1676 m_VisAttributes.push_back(
new G4VisAttributes(
true, G4Colour(0., 1., 0.)));
1677 for (
const auto& cover2 : geom.getCover2s()) {
1678 const int cover2ID = cover2.getId();
1679 const string cover2Name =
"cover2" + to_string(cover2ID);
1680 const double rmin = cover2.getRmin();
1681 const double rmax = cover2.getRmax();
1682 const double phis = cover2.getPhis();
1683 const double dphi = cover2.getDphi();
1684 const double thick = cover2.getThick();
1685 const double posZ = cover2.getZ();
1688 createTube2(rmin, rmax, phis, dphi, thick, posZ, cover2ID, medHV, cover2Name);
1689 if (cover2ID > 10 && cover2ID < 14)
1690 createTube2(rmin, rmax, phis, dphi, thick, posZ, cover2ID, medFiber, cover2Name);
1691 if (cover2ID > 13 && cover2ID < 23)
1692 createTube2(rmin, rmax, phis, dphi, thick, posZ, cover2ID, medCAT7, cover2Name);
1693 if (cover2ID > 22 && cover2ID < 29)
1694 createTube2(rmin, rmax, phis, dphi, thick, posZ, cover2ID, medTRG, cover2Name);
1699 const double rmin2,
const double rmax2,
1700 const double thick,
const double posZ,
1701 const int id, G4Material* med,
1704 const string solidName =
"solid" + name;
1705 const string logicalName =
"logical" + name;
1706 const string physicalName =
"physical" + name;
1707 G4Cons* coverConeShape =
new G4Cons(solidName.c_str(), rmin1 * CLHEP::cm, rmax1 * CLHEP::cm,
1708 rmin2 * CLHEP::cm, rmax2 * CLHEP::cm, thick * CLHEP::cm / 2.0, 0.*CLHEP::deg, 360.*CLHEP::deg);
1709 G4LogicalVolume* coverCone =
new G4LogicalVolume(coverConeShape, med,
1710 logicalName.c_str(), 0, 0, 0);
1712 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, posZ * CLHEP::cm - thick * CLHEP::cm / 2.0), coverCone,
1718 const double thick,
const double posZ,
1719 const int id, G4Material* med,
1722 const string solidName =
"solid" + name;
1723 const string logicalName =
"logical" + name;
1724 const string physicalName =
"physical" + name;
1725 G4Tubs* solidV =
new G4Tubs(solidName.c_str(),
1728 thick * CLHEP::cm / 2.0,
1731 G4LogicalVolume* logicalV =
new G4LogicalVolume(solidV, med,
1732 logicalName.c_str(), 0, 0, 0);
1734 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, posZ * CLHEP::cm - thick * CLHEP::cm / 2.0), logicalV,
1740 const double thick,
const double x,
1741 const double y,
const double z,
1742 const int id, G4Material* med,
1745 const string solidName = (format(
"solid%1%%2%") % name % id).str();
1746 const string logicalName = (format(
"logical%1%%2%") % name % id).str();
1747 const string physicalName = (format(
"physical%1%%2%") % name % id).str();
1748 G4Box* boxShape =
new G4Box(solidName.c_str(), 0.5 * length * CLHEP::cm,
1749 0.5 * height * CLHEP::cm,
1750 0.5 * thick * CLHEP::cm);
1751 G4LogicalVolume* logicalV =
new G4LogicalVolume(boxShape, med,
1752 logicalName.c_str(), 0, 0, 0);
1754 new G4PVPlacement(0, G4ThreeVector(x * CLHEP::cm, y * CLHEP::cm, z * CLHEP::cm - thick * CLHEP::cm / 2.0), logicalV,
1760 const double thick,
const double posZ,
1761 const int id, G4Material* med,
1764 const string solidName =
"solid" + name;
1765 const string logicalName =
"logical" + name;
1766 const string physicalName =
"physical" + name;
1767 const double rtor = (rmax1 + rmin1) / 2.;
1768 const double rmax = rmax1 - rtor;
1769 const double rmin = max((rmax - thick), 0.);
1771 G4Torus* solidV =
new G4Torus(solidName.c_str(),
1777 G4LogicalVolume* logicalV =
new G4LogicalVolume(solidV, med,
1778 logicalName.c_str(), 0, 0, 0);
1780 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, posZ * CLHEP::cm), logicalV,
1786 const double phis,
const double phie,
1787 const double thick,
const double posZ,
1788 const int id, G4Material* med,
1791 const string solidName =
"solid" + name;
1792 const string logicalName =
"logical" + name;
1793 const string physicalName =
"physical" + name;
1794 G4Tubs* solidV =
new G4Tubs(solidName.c_str(),
1797 thick * CLHEP::cm / 2.0,
1800 G4LogicalVolume* logicalV =
new G4LogicalVolume(solidV, med,
1801 logicalName.c_str(), 0, 0, 0);
1803 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, posZ * CLHEP::cm - thick * CLHEP::cm / 2.0), logicalV,
1813 const double xc = 0.5 * (-0.0002769 + 0.0370499) * CLHEP::cm;
1814 const double yc = 0.5 * (-0.0615404 + -0.108948) * CLHEP::cm;
1815 const double zc = 0.5 * (-35.3 + 48.5) * CLHEP::cm;
1820 const double plateWidth = 13.8 * CLHEP::cm;
1821 const double plateThick = 1.2 * CLHEP::cm;
1822 const double plateLength = 83.8 * CLHEP::cm;
1828 const double endPlateRmin = 4.0 * CLHEP::cm;
1829 const double endPlateRmax = 15.5 * CLHEP::cm;
1830 const double bwdEndPlateThick = 1.7 * CLHEP::cm;
1831 const double fwdEndPlateThick = 2.0 * CLHEP::cm;
1835 string name =
"Plate";
1837 G4Box* plateShape =
new G4Box(
"solid" + name, .5 * plateWidth, .5 * plateThick, .5 * plateLength);
1838 G4LogicalVolume* logical0 =
new G4LogicalVolume(plateShape, medAluminum,
"logical" + name, 0, 0, 0);
1841 const double x = xc + 0.5 * plateWidth;
1843 const double y = yc + endPlateRmin + 0.1 * CLHEP::cm;
1845 G4ThreeVector xyz(x, y, zc);
1846 G4RotationMatrix rotM3 = G4RotationMatrix();
1849 new G4PVPlacement(G4Transform3D(rotM3, xyz), logical0,
"physical" + name, &topVolume,
false, pID);
1851 const double alf = 120. * CLHEP::deg;
1854 new G4PVPlacement(G4Transform3D(rotM3, xyz), logical0,
"physical" + name, &topVolume,
false, pID + 1);
1858 new G4PVPlacement(G4Transform3D(rotM3, xyz), logical0,
"physical" + name, &topVolume,
false, pID + 2);
1862 name =
"BwdEndPlate";
1863 G4Tubs* BwdEndPlateShape =
new G4Tubs(
"solid" + name, endPlateRmin, endPlateRmax, 0.5 * bwdEndPlateThick, 0., 360.*CLHEP::deg);
1864 G4LogicalVolume* logical1 =
new G4LogicalVolume(BwdEndPlateShape, medAluminum,
"logical" + name, 0, 0, 0);
1867 double z = -35.3 * CLHEP::cm - 0.5 * bwdEndPlateThick;
1869 new G4PVPlacement(0, G4ThreeVector(xc, yc, z), logical1,
"physical" + name, &topVolume,
false, pID);
1874 name =
"FwdEndPlate";
1875 G4Tubs* FwdEndPlateShape =
new G4Tubs(
"solid" + name, endPlateRmin, endPlateRmax, 0.5 * fwdEndPlateThick, 0., 360.*CLHEP::deg);
1876 G4LogicalVolume* logical2 =
new G4LogicalVolume(FwdEndPlateShape, medAluminum,
"logical" + name, 0, 0, 0);
1878 z = 48.5 * CLHEP::cm + 0.5 * fwdEndPlateThick;
1879 new G4PVPlacement(0, G4ThreeVector(xc, yc, z), logical2,
"physical" + name, &topVolume,
false, pID);
DataType Z() const
access variable Z (= .at(2) without boundary check)
void SetX(DataType x)
set X/1st-coordinate
B2Vector3< DataType > Cross(const B2Vector3< DataType > &p) const
Cross product.
DataType X() const
access variable X (= .at(0) without boundary check)
DataType Y() const
access variable Y (= .at(1) without boundary check)
DataType Mag() const
The magnitude (rho in spherical coordinate system).
void SetY(DataType y)
set Y/2nd-coordinate
DataType Perp() const
The transverse component (R in cylindrical coordinate system).
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.
std::vector< double > getRmin() const
Get the list of the Rmin corrdinates.
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.
OuterWall getOuterWall(int i) const
Get the i-th outer wall.
std::vector< Rib2 > getRib2s() const
Get the list of rib2s.
double getFiducialRmin() const
Get the fiducial Rmin of CDC sensitive volume.
std::vector< Rib > getRibs() const
Get the list of ribs.
double getGlobalOffsetX() const
Get the global x offset of CDC wrt Belle2 coord.
std::vector< InnerWall > getInnerWalls() const
Get the list of inner walls.
std::vector< Rib5 > getRib5s() const
Get the list of rib5s.
double getFiducialRmax() const
Get the fiducial Rmax of CDC sensitive volume.
int getNFieldWires() const
Get the number of field wires.
std::vector< Rib3 > getRib3s() const
Get the list of rib3s.
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< Frontend > getFrontends() const
Get the list of frontend layers.
InnerWall getInnerWall(int i) const
Get the i-th inner wall.
double getFieldDiameter() const
Get the diameter of field wire.
EndPlate getEndPlate(int i) const
Get the i-th endplate.
std::vector< Rib4 > getRib4s() const
Get the list of rib4s.
int getNSenseLayers() const
Get the number of sense layers.
std::vector< EndPlate > getEndPlates() const
Get the list of endplates.
double getFeedthroughLength() const
Get the length of feedthrough.
double getGlobalOffsetZ() const
Get the global z offset of CDC wrt Belle2 coord.
std::vector< OuterWall > getOuterWalls() const
Get the list of outer walls.
SenseLayer getSenseLayer(int i) const
Get i-th sense layer.
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.
static CDCGeoControlPar & getInstance()
Static method to get a reference to the CDCGeoControlPar instance.
The Class for CDC Geometry Parameters.
double fieldWireDiameter() const
Returns diameter of the field wire.
const B2Vector3D wireForwardPosition(uint 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.
const B2Vector3D wireBackwardPosition(uint layerId, int cellId, EWirePosition set=c_Base) const
Returns the backward position of the input sense wire.
unsigned nWiresInLayer(int layerId) const
Returns wire numbers in a layer.
static CDCGeometryPar & Instance(const CDCGeometry *=nullptr)
Static method to get a reference to the CDCGeometryPar instance.
The Class for CDC Sensitive Detector.
static CDCSimControlPar & getInstance()
Static method to get a reference to the CDCSimControlPar instance.
void createBox(const double length, const double height, const double thick, const double x, const double y, const double z, const int id, G4Material *med, const std::string &name)
Create G4Box.
GeoCDCCreatorReducedCDC()
Constructor of the GeoCDCCreatorReducedCDC class.
std::vector< G4VisAttributes * > m_VisAttributes
Vector of pointers to G4VisAttributes.
std::vector< G4UserLimits * > m_userLimits
Vector of pointers to G4UserLimits.
BkgSensitiveDetector * m_bkgsensitive
Sensitive detector for background studies.
void createGeometry(const CDCGeometry ¶meters, G4LogicalVolume &topVolume, geometry::GeometryTypes type)
Create G4 geometry of CDC.
void createTube2(const double rmin, const double rmax, const double phis, const double phie, const double thick, const double posZ, const int id, G4Material *med, const std::string &name)
Create G4Tube2.
void createTube(const double rmin, const double rmax, const double thick, const double posZ, const int id, G4Material *med, const std::string &name)
Create G4Tube.
~GeoCDCCreatorReducedCDC()
The destructor of the GeoCDCCreatorReducedCDC class.
void createNeutronShields(const GearDir &content)
Create neutron shield from gearbox.
G4VPhysicalVolume * m_physicalCDC
CDC G4 physical volume.
void createTorus(const double rmin1, const double rmax1, const double thick, const double posZ, const int id, G4Material *med, const std::string &name)
Create G4Torus.
void createCone(const double rmin1, const double rmax1, const double rmin2, const double rmax2, const double thick, const double posz, const int id, G4Material *med, const std::string &name)
Create G4Cone.
void createCover2s(const GearDir &content)
Create CDC cover2s from gear box.
void createMapper(G4LogicalVolume &topVolume)
Create the B-field mapper geometry (tentative function)
G4LogicalVolume * m_logicalCDC
CDC G4 logical volume.
void createCovers(const GearDir &content)
Create CDC covers from gear box.
CDCSensitiveDetector * m_sensitive
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.
static G4Material * get(const std::string &name)
Find given material.
geometry::CreatorFactory< GeoCDCCreatorReducedCDC > GeoCDCFactoryReducedCDC("CDCCreatorReducedCDC")
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.