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>
51 using namespace geometry;
77 B2WARNING(
"Using CDC without SL0!");
87 for (G4UserLimits* userLimits :
m_userLimits)
delete userLimits;
96 const G4double realTemperture = (273.15 + 23.) * CLHEP::kelvin;
106 G4double h2odensity = 1.000 * CLHEP::g / CLHEP::cm3;
107 G4double a = 1.01 * CLHEP::g / CLHEP::mole;
108 G4Element* elH =
new G4Element(
"Hydrogen",
"H", 1., a);
109 a = 16.00 * CLHEP::g / CLHEP::mole;
110 G4Element* elO =
new G4Element(
"Oxygen",
"O", 8., a);
111 G4Material* medH2O =
new G4Material(
"Water", h2odensity, 2);
112 medH2O->AddElement(elH, 2);
113 medH2O->AddElement(elO, 1);
125 const double num_senseWire =
static_cast<double>(geo.
getNSenseWires());
126 const double num_fieldWire =
static_cast<double>(geo.
getNFieldWires());
127 double totalCS = M_PI * (rmin_outerWall * rmin_outerWall - rmax_innerWall * rmax_innerWall);
130 double senseCS = M_PI * (diameter_senseWire / 2) * (diameter_senseWire / 2) * num_senseWire;
133 double fieldCS = M_PI * (diameter_fieldWire / 2) * (diameter_fieldWire / 2) * num_fieldWire;
136 const double denHelium = medHelium->GetDensity() / 2.0;
137 const double denEthane = medEthane->GetDensity() / 2.0;
138 const double denAluminum = medAluminum->GetDensity() * (fieldCS / totalCS);
139 const double denTungsten = medTungsten->GetDensity() * (senseCS / totalCS);
140 const double density = denHelium + denEthane + denAluminum + denTungsten;
141 G4Material* cdcMed =
new G4Material(
"CDCGasWire", density, 4, kStateGas, realTemperture);
142 cdcMed->AddMaterial(medHelium, denHelium / density);
143 cdcMed->AddMaterial(medEthane, denEthane / density);
144 cdcMed->AddMaterial(medTungsten, denTungsten / density);
145 cdcMed->AddMaterial(medAluminum, denAluminum / density);
147 G4Material* cdcMedGas = cdcMed;
155 const double density2 = denHelium + denEthane;
156 cdcMedGas =
new G4Material(
"CDCRealGas", density2, 2, kStateGas, realTemperture);
157 cdcMedGas->AddMaterial(medHelium, denHelium / density2);
158 cdcMedGas->AddMaterial(medEthane, denEthane / density2);
162 G4cout << *(G4Material::GetMaterialTable());
166 const auto& motherRmin = mother.
getRmin();
167 const auto& motherRmax = mother.getRmax();
168 const auto& motherZ = mother.getZ();
169 G4Polycone* solid_cdc =
170 new G4Polycone(
"solidCDC", 0 * CLHEP::deg, 360.* CLHEP::deg,
171 mother.getNNodes(), motherZ.data(),
172 motherRmin.data(), motherRmax.data());
173 m_logicalCDC =
new G4LogicalVolume(solid_cdc, medAir,
"logicalCDC", 0, 0, 0);
177 "physicalCDC", &topVolume,
false, 0);
180 G4Region* aRegion =
new G4Region(
"CDCEnvelope");
184 m_VisAttributes.push_back(
new G4VisAttributes(
true, G4Colour(0., 1., 0.)));
186 const int iOuterWall = wall.getId();
187 const string wallName = wall.getName();
188 const double wallRmin = wall.getRmin();
189 const double wallRmax = wall.getRmax();
190 const double wallZfwd = wall.getZfwd();
191 const double wallZbwd = wall.getZbwd();
192 const double length = (wallZfwd - wallZbwd) / 2.0;
196 if (strstr((wallName).c_str(),
"MiddleWall") !=
nullptr) {
199 medWall = medAluminum;
201 G4Tubs* outerWallTubeShape =
new G4Tubs(
"solid" + wallName, wallRmin * CLHEP::cm,
202 wallRmax * CLHEP::cm, length * CLHEP::cm, 0 * CLHEP::deg, 360.*CLHEP::deg);
204 G4LogicalVolume* outerWallTube =
new G4LogicalVolume(outerWallTubeShape, medWall,
"solid" + wallName, 0, 0, 0);
206 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (length + wallZbwd)*CLHEP::cm), outerWallTube,
"logical" + wallName,
211 m_VisAttributes.push_back(
new G4VisAttributes(
true, G4Colour(0., 1., 0.)));
213 const string wallName = wall.getName();
214 const double wallRmin = wall.getRmin();
215 const double wallRmax = wall.getRmax();
216 const double wallZfwd = wall.getZfwd();
217 const double wallZbwd = wall.getZbwd();
218 const double length = (wallZfwd - wallZbwd) / 2.0;
219 const int iInnerWall = wall.getId();
222 if (strstr(wallName.c_str(),
"MiddleWall") !=
nullptr) {
224 }
else if (strstr(wallName.c_str(),
"MiddleGlue") !=
nullptr) {
227 medWall = medAluminum;
230 G4Tubs* innerWallTubeShape =
new G4Tubs(
"solid" + wallName, wallRmin * CLHEP::cm,
231 wallRmax * CLHEP::cm, length * CLHEP::cm, 0 * CLHEP::deg, 360.*CLHEP::deg);
232 G4LogicalVolume* innerWallTube =
new G4LogicalVolume(innerWallTubeShape, medWall,
"logical" + wallName, 0, 0, 0);
234 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (length + wallZbwd)*CLHEP::cm), innerWallTube,
"physical" + wallName,
247 for (uint iSLayer = 0; iSLayer < nSLayer; ++iSLayer) {
251 double rmin_sensitive_left, rmax_sensitive_left;
252 double rmin_sensitive_middle, rmax_sensitive_middle;
253 double rmin_sensitive_right, rmax_sensitive_right;
254 double zback_sensitive_left, zfor_sensitive_left;
255 double zback_sensitive_middle, zfor_sensitive_middle;
256 double zback_sensitive_right, zfor_sensitive_right;
259 const auto& epLayerBwd = endplate.getEndPlateLayer(1);
260 const auto& epLayerFwd = endplate.getEndPlateLayer((nEPLayer / 2) + 1);
264 rmin_sensitive_left = epLayerBwd.getRmax();
265 rmax_sensitive_left = fieldLayer.
getR();
266 zback_sensitive_left = senseLayer.getZbwd();
267 zfor_sensitive_left = epLayerBwd.getZfwd();
269 rmin_sensitive_middle = (geo.
getInnerWall(0)).getRmax();
270 rmax_sensitive_middle = fieldLayer.getR();
271 zback_sensitive_middle = epLayerBwd.getZfwd();
272 zfor_sensitive_middle = epLayerFwd.getZbwd();
274 rmin_sensitive_right = epLayerFwd.getRmax();
275 rmax_sensitive_right = fieldLayer.getR();
276 zback_sensitive_right = epLayerFwd.getZbwd();
277 zfor_sensitive_right = senseLayer.getZfwd();
278 }
else if (iSLayer >= 1 && iSLayer <= 6) {
279 const auto& epLayerBwd = endplate.getEndPlateLayer(1);
280 const auto& epLayerFwd = endplate.getEndPlateLayer((nEPLayer / 2) + 1);
285 rmin_sensitive_left = epLayerBwd.getRmax();
286 rmax_sensitive_left = fieldLayerOut.
getR();
287 zback_sensitive_left = senseLayer.getZbwd();
288 zfor_sensitive_left = epLayerBwd.getZfwd();
290 rmin_sensitive_middle = fieldLayerIn.getR();
291 rmax_sensitive_middle = fieldLayerOut.getR();
292 zback_sensitive_middle = epLayerBwd.getZfwd();
293 zfor_sensitive_middle = epLayerFwd.getZbwd();
295 rmin_sensitive_right = epLayerFwd.getRmax();
296 rmax_sensitive_right = fieldLayerOut.getR();
297 zback_sensitive_right = epLayerFwd.getZbwd();
298 zfor_sensitive_right = senseLayer.getZfwd();
299 }
else if (iSLayer >= 7 && iSLayer <= 10) {
300 const auto& epLayerBwd = endplate.getEndPlateLayer(1);
301 const auto& epLayerFwd = endplate.getEndPlateLayer(nEPLayer / 2);
306 rmin_sensitive_left = epLayerBwd.getRmax();
307 rmax_sensitive_left = fieldLayerOut.
getR();
308 zback_sensitive_left = senseLayer.getZbwd();
309 zfor_sensitive_left = epLayerBwd.getZfwd();
311 rmin_sensitive_middle = fieldLayerIn.getR();
312 rmax_sensitive_middle = fieldLayerOut.getR();
313 zback_sensitive_middle = epLayerBwd.getZfwd();
314 zfor_sensitive_middle = epLayerFwd.getZbwd();
316 rmin_sensitive_right = epLayerFwd.getRmax();
317 rmax_sensitive_right = fieldLayerOut.getR();
318 zback_sensitive_right = epLayerFwd.getZbwd();
319 zfor_sensitive_right = senseLayer.getZfwd();
320 }
else if (iSLayer >= 11 && iSLayer < 47) {
321 const auto& epLayerBwd = endplate.getEndPlateLayer(0);
322 const auto& epLayerFwd = endplate.getEndPlateLayer(nEPLayer / 2);
327 rmin_sensitive_left = epLayerBwd.getRmax();
328 rmax_sensitive_left = fieldLayerOut.
getR();
329 zback_sensitive_left = senseLayer.getZbwd();
330 zfor_sensitive_left = epLayerBwd.getZfwd();
332 rmin_sensitive_middle = fieldLayerIn.getR();
333 rmax_sensitive_middle = fieldLayerOut.getR();
334 zback_sensitive_middle = epLayerBwd.getZfwd();
335 zfor_sensitive_middle = epLayerFwd.getZbwd();
337 rmin_sensitive_right = epLayerFwd.getRmax();
338 rmax_sensitive_right = fieldLayerOut.getR();
339 zback_sensitive_right = epLayerFwd.getZbwd();
340 zfor_sensitive_right = senseLayer.getZfwd();
342 }
else if (iSLayer == 47) {
344 const auto& epLayerBwdIn = endplate.getEndPlateLayer(0);
345 const auto& epLayerBwdOut = endplate.getEndPlateLayer((nEPLayer / 2) - 1);
346 const auto& epLayerFwdIn = endplate.getEndPlateLayer(nEPLayer / 2);
347 const auto& epLayerFwdOut = endplate.getEndPlateLayer(nEPLayer - 1);
350 int iSLayerMinus1 = iSLayer - 1;
352 rmin_sensitive_left = epLayerBwdIn.getRmax();
353 rmax_sensitive_left = epLayerBwdOut.getRmax();
354 zback_sensitive_left = senseLayer.
getZbwd();
355 zfor_sensitive_left = epLayerBwdIn.getZfwd();
357 rmin_sensitive_middle = fieldLayerIn.getR();
358 rmax_sensitive_middle = (geo.
getOuterWall(0)).getRmin();
359 zback_sensitive_middle = epLayerBwdIn.getZfwd();
360 zfor_sensitive_middle = epLayerFwdIn.getZbwd();
362 rmin_sensitive_right = epLayerFwdIn.getRmax();
363 rmax_sensitive_right = epLayerFwdOut.getRmax();
364 zback_sensitive_right = epLayerFwdIn.getZbwd();
365 zfor_sensitive_right = senseLayer.getZfwd();
368 B2ERROR(
"Undefined sensitive layer : " << iSLayer);
374 if ((zfor_sensitive_left - zback_sensitive_left) > length_feedthrough) {
391 G4Tubs* leftTubeShape =
new G4Tubs((boost::format(
"solidCDCLayer_%1%_leftTube") % iSLayer).str().c_str(),
392 rmin_sensitive_left * CLHEP::cm,
393 rmax_sensitive_left * CLHEP::cm, length_feedthrough * CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
394 G4LogicalVolume* leftTube =
new G4LogicalVolume(leftTubeShape, cdcMed,
395 (boost::format(
"logicalCDCLayer_%1%_leftTube") % iSLayer).str().c_str(), 0, 0, 0);
396 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zback_sensitive_left + length_feedthrough / 2.0)*CLHEP::cm), leftTube,
397 (boost::format(
"physicalCDCLayer_%1%_leftTube") % iSLayer).str().c_str(),
m_logicalCDC,
false, iSLayer);
399 G4Tubs* leftSensitiveTubeShape =
new G4Tubs((boost::format(
"solidSD_CDCLayer_%1%_left") % iSLayer).str().c_str(),
400 rmin_sensitive_left * CLHEP::cm, rmax_sensitive_left * CLHEP::cm,
401 (zfor_sensitive_left - zback_sensitive_left - length_feedthrough)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
402 G4LogicalVolume* leftSensitiveTube =
new G4LogicalVolume(leftSensitiveTubeShape, cdcMed,
403 (boost::format(
"logicalSD_CDCLayer_%1%_left") % iSLayer).str().c_str(), 0, 0, 0);
404 leftSensitiveTube->SetSensitiveDetector(
m_sensitive);
405 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfor_sensitive_left + zback_sensitive_left + length_feedthrough)*CLHEP::cm / 2.0),
406 leftSensitiveTube, (boost::format(
"physicalSD_CDCLayer_%1%_left") % iSLayer).str().c_str(),
m_logicalCDC,
false, iSLayer);
424 G4Tubs* leftTubeShape =
new G4Tubs((boost::format(
"solidCDCLayer_%1%_leftTube") % iSLayer).str().c_str(),
425 rmin_sensitive_left * CLHEP::cm,
426 rmax_sensitive_left * CLHEP::cm, (zfor_sensitive_left - zback_sensitive_left)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
427 G4LogicalVolume* leftTube =
new G4LogicalVolume(leftTubeShape, cdcMed,
428 (boost::format(
"logicalCDCLayer_%1%_leftTube") % iSLayer).str().c_str(), 0, 0, 0);
429 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfor_sensitive_left + zback_sensitive_left)*CLHEP::cm / 2.0), leftTube,
430 (boost::format(
"physicalCDCLayer_%1%_leftTube") % iSLayer).str().c_str(),
m_logicalCDC,
false, iSLayer);
434 G4Tubs* leftMidTubeShape =
new G4Tubs((boost::format(
"solidCDCLayer_%1%_leftMidTube") % iSLayer).str().c_str(),
435 rmin_sensitive_middle * CLHEP::cm, rmax_sensitive_middle * CLHEP::cm,
436 (length_feedthrough - zfor_sensitive_left + zback_sensitive_left)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
437 G4LogicalVolume* leftMidTube =
new G4LogicalVolume(leftMidTubeShape, cdcMed,
438 (boost::format(
"logicalCDCLayer_%1%_leftMidTube") % iSLayer).str().c_str(), 0, 0, 0);
440 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (length_feedthrough + zfor_sensitive_left + zback_sensitive_left)*CLHEP::cm / 2.0),
441 leftMidTube, (boost::format(
"physicalCDCLayer_%1%_leftMidTube") % iSLayer).str().c_str(),
m_logicalCDC,
false, iSLayer);
444 zback_sensitive_middle = length_feedthrough + zback_sensitive_left;
448 if ((zfor_sensitive_right - zback_sensitive_right) > length_feedthrough) {
465 G4Tubs* rightTubeShape =
new G4Tubs((boost::format(
"solidCDCLayer_%1%_rightTube") % iSLayer).str().c_str(),
466 rmin_sensitive_right * CLHEP::cm, rmax_sensitive_right * CLHEP::cm, length_feedthrough * CLHEP::cm / 2.0, 0 * CLHEP::deg,
468 G4LogicalVolume* rightTube =
new G4LogicalVolume(rightTubeShape, cdcMed,
469 (boost::format(
"logicalCDCLayer_%1%_rightTube") % iSLayer).str().c_str(), 0, 0, 0);
471 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfor_sensitive_right - length_feedthrough / 2.0)*CLHEP::cm), rightTube,
472 (boost::format(
"physicalCDCLayer_%1%_rightTube") % iSLayer).str().c_str(),
m_logicalCDC,
false, iSLayer);
476 G4Tubs* rightSensitiveTubeShape =
new G4Tubs((boost::format(
"solidSD_CDCLayer_%1%_right") % iSLayer).str().c_str(),
477 rmin_sensitive_right * CLHEP::cm, rmax_sensitive_right * CLHEP::cm,
478 (zfor_sensitive_right - zback_sensitive_right - length_feedthrough)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
479 G4LogicalVolume* rightSensitiveTube =
new G4LogicalVolume(rightSensitiveTubeShape, cdcMed,
480 (boost::format(
"logicalSD_CDCLayer_%1%_right") % iSLayer).str().c_str(), 0, 0, 0);
481 rightSensitiveTube->SetSensitiveDetector(
m_sensitive);
483 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfor_sensitive_right + zback_sensitive_right - length_feedthrough)*CLHEP::cm / 2.0),
484 rightSensitiveTube, (boost::format(
"physicalSD_CDCLayer_%1%_right") % iSLayer).str().c_str(),
m_logicalCDC,
false, iSLayer);
503 G4Tubs* rightTubeShape =
new G4Tubs((boost::format(
"solidCDCLayer_%1%_rightTube") % iSLayer).str().c_str(),
504 rmin_sensitive_right * CLHEP::cm, rmax_sensitive_right * CLHEP::cm, (zfor_sensitive_right - zback_sensitive_right)*CLHEP::cm / 2.0,
505 0 * CLHEP::deg, 360.*CLHEP::deg);
506 G4LogicalVolume* rightTube =
new G4LogicalVolume(rightTubeShape, cdcMed,
507 (boost::format(
"logicalCDCLayer_%1%_rightTube") % iSLayer).str().c_str(), 0, 0, 0);
509 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfor_sensitive_right + zback_sensitive_right)*CLHEP::cm / 2.0), rightTube,
510 (boost::format(
"physicalCDCLayer_%1%_rightTube") % iSLayer).str().c_str(),
m_logicalCDC,
false, iSLayer);
514 G4Tubs* rightMidTubeShape =
new G4Tubs((boost::format(
"solidCDCLayer_%1%_rightMidTube") % iSLayer).str().c_str(),
515 rmin_sensitive_middle * CLHEP::cm, rmax_sensitive_middle * CLHEP::cm,
516 (length_feedthrough - zfor_sensitive_right + zback_sensitive_right)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
517 G4LogicalVolume* rightMidTube =
new G4LogicalVolume(rightMidTubeShape, cdcMed,
518 (boost::format(
"logicalCDCLayer_%1%_rightMidTube") % iSLayer).str().c_str(), 0, 0, 0);
519 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zback_sensitive_right - length_feedthrough + zfor_sensitive_right)*CLHEP::cm / 2.0),
520 rightMidTube, (boost::format(
"physicalCDCLayer_%1%_rightMidTube") % iSLayer).str().c_str(),
m_logicalCDC,
false, iSLayer);
523 zfor_sensitive_middle = zfor_sensitive_right - length_feedthrough;
528 G4Tubs* middleSensitiveTubeShape =
new G4Tubs((boost::format(
"solidSD_CDCLayer_%1%_middle") % iSLayer).str().c_str(),
529 rmin_sensitive_middle * CLHEP::cm, rmax_sensitive_middle * CLHEP::cm,
530 (zfor_sensitive_middle - zback_sensitive_middle)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
531 G4LogicalVolume* middleSensitiveTube =
new G4LogicalVolume(middleSensitiveTubeShape, cdcMedGas,
532 (boost::format(
"logicalSD_CDCLayer_%1%_middle") % iSLayer).str().c_str(), 0, 0, 0);
535 G4UserLimits* uLimits =
new G4UserLimits(8.5 * CLHEP::cm);
537 middleSensitiveTube->SetUserLimits(uLimits);
538 middleSensitiveTube->SetSensitiveDetector(
m_sensitive);
540 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfor_sensitive_middle + zback_sensitive_middle)*CLHEP::cm / 2.0), middleSensitiveTube,
541 (boost::format(
"physicalSD_CDCLayer_%1%_middle") % iSLayer).str().c_str(),
m_logicalCDC,
false, iSLayer);
545 G4String sName =
"sWire";
550 G4double tAtZ0 = -wb0.
Z() / (wf0.
Z() - wb0.
Z());
553 const G4double epsl = 25.e-4;
554 G4double reductionBwd = (zback_sensitive_middle + epsl) / wb0.
Z();
556 wb0 = reductionBwd * (wb0 - wAtZ0) + wAtZ0;
558 G4double reductionFwd = (zfor_sensitive_middle - epsl) / wf0.
Z();
559 wf0 = reductionFwd * (wf0 - wAtZ0) + wAtZ0;
561 const G4double wireHalfLength = 0.5 * (wf0 - wb0).Mag() * CLHEP::cm;
564 G4Tubs* middleSensitiveSwireShape =
new G4Tubs(sName, 0., sWireRadius, wireHalfLength, 0., 360. * CLHEP::deg);
565 G4LogicalVolume* middleSensitiveSwire =
new G4LogicalVolume(middleSensitiveSwireShape, medTungsten, sName);
569 G4String fName =
"fWire";
571 G4Tubs* middleSensitiveFwireShape =
new G4Tubs(fName, 0., fWireRadius, wireHalfLength, 0., 360. * CLHEP::deg);
572 G4LogicalVolume* middleSensitiveFwire =
new G4LogicalVolume(middleSensitiveFwireShape, medAluminum, fName);
579 const G4double dphi = M_PI / nCells;
582 for (
int ic = 0; ic < nCells; ++ic) {
586 G4double tAtZ02 = -wb.Z() / (wf.
Z() - wb.Z());
588 G4double reductionBwd2 = (zback_sensitive_middle + epsl) / wb.Z();
589 wb = reductionBwd2 * (wb - wAtZ02) + wAtZ02;
590 G4double reductionFwd2 = (zfor_sensitive_middle - epsl) / wf.
Z();
591 wf = reductionFwd2 * (wf - wAtZ02) + wAtZ02;
593 G4double thetaYZ = -asin((wf - wb).Y() / (wf - wb).Mag());
595 B2Vector3D fMinusBInZX((wf - wb).X(), 0., (wf - wb).Z());
596 G4double thetaZX = asin((unitZ.
Cross(fMinusBInZX)).Y() / fMinusBInZX.
Mag());
597 G4RotationMatrix rotM;
599 rotM.rotateX(thetaYZ * CLHEP::rad);
600 rotM.rotateY(thetaZX * CLHEP::rad);
602 G4ThreeVector xyz(0.5 * (wb.X() + wf.
X()) * CLHEP::cm,
603 0.5 * (wb.Y() + wf.
Y()) * CLHEP::cm, 0.);
607 new G4PVPlacement(G4Transform3D(rotM, xyz), middleSensitiveSwire, sName, middleSensitiveTube,
false, ic);
611 G4double rF = rmax_sensitive_middle - 0.5 * diameter;
613 G4double phi = atan2(wbF.
Y(), wbF.
X());
614 wbF.
SetX(rF * cos(phi));
615 wbF.
SetY(rF * sin(phi));
618 rF = rmax_sensitive_middle - 0.5 * diameter;
619 phi = atan2(wfF.
Y(), wfF.
X());
620 wfF.
SetX(rF * cos(phi));
621 wfF.
SetY(rF * sin(phi));
623 thetaYZ = -asin((wfF - wbF).Y() / (wfF - wbF).Mag());
625 fMinusBInZX = wfF - wbF;
626 fMinusBInZX.
SetY(0.);
627 thetaZX = asin((unitZ.
Cross(fMinusBInZX)).Y() / fMinusBInZX.
Mag());
629 G4RotationMatrix rotM1;
630 rotM1.rotateX(thetaYZ * CLHEP::rad);
631 rotM1.rotateY(thetaZX * CLHEP::rad);
633 xyz.setX(0.5 * (wbF.
X() + wfF.
X()) * CLHEP::cm);
634 xyz.setY(0.5 * (wbF.
Y() + wfF.
Y()) * CLHEP::cm);
636 if (iSLayer != nSLayer - 1) {
638 new G4PVPlacement(G4Transform3D(rotM1, xyz), middleSensitiveFwire, fName, middleSensitiveTube,
false, ic);
644 phi = atan2(wbF.
Y(), wbF.
X());
645 wbF.
SetX(rF * cos(phi + dphi));
646 wbF.
SetY(rF * sin(phi + dphi));
650 phi = atan2(wfF.
Y(), wfF.
X());
651 wfF.
SetX(rF * cos(phi + dphi));
652 wfF.
SetY(rF * sin(phi + dphi));
654 thetaYZ = -asin((wfF - wbF).Y() / (wfF - wbF).Mag());
656 fMinusBInZX = wfF - wbF;
657 fMinusBInZX.
SetY(0.);
658 thetaZX = asin((unitZ.
Cross(fMinusBInZX)).Y() / fMinusBInZX.
Mag());
660 G4RotationMatrix rotM2;
661 rotM2.rotateX(thetaYZ * CLHEP::rad);
662 rotM2.rotateY(thetaZX * CLHEP::rad);
664 xyz.setX(0.5 * (wbF.
X() + wfF.
X()) * CLHEP::cm);
665 xyz.setY(0.5 * (wbF.
Y() + wfF.
Y()) * CLHEP::cm);
668 new G4PVPlacement(G4Transform3D(rotM2, xyz), middleSensitiveFwire, fName, middleSensitiveTube,
false, ic + nCells);
672 rF = rmax_sensitive_middle - 0.5 * diameter;
673 phi = atan2(wbF.
Y(), wbF.
X());
674 wbF.
SetX(rF * cos(phi + dphi));
675 wbF.
SetY(rF * sin(phi + dphi));
678 rF = rmax_sensitive_middle - 0.5 * diameter;
679 phi = atan2(wfF.
Y(), wfF.
X());
680 wfF.
SetX(rF * cos(phi + dphi));
681 wfF.
SetY(rF * sin(phi + dphi));
683 thetaYZ = -asin((wfF - wbF).Y() / (wfF - wbF).Mag());
685 fMinusBInZX = wfF - wbF;
686 fMinusBInZX.
SetY(0.);
687 thetaZX = asin((unitZ.
Cross(fMinusBInZX)).Y() / fMinusBInZX.
Mag());
689 G4RotationMatrix rotM3;
690 rotM3.rotateX(thetaYZ * CLHEP::rad);
691 rotM3.rotateY(thetaZX * CLHEP::rad);
693 xyz.setX(0.5 * (wbF.
X() + wfF.
X()) * CLHEP::cm);
694 xyz.setY(0.5 * (wbF.
Y() + wfF.
Y()) * CLHEP::cm);
696 if (iSLayer != nSLayer - 1) {
697 new G4PVPlacement(G4Transform3D(rotM3, xyz), middleSensitiveFwire, fName, middleSensitiveTube,
false, ic + 2 * nCells);
707 m_VisAttributes.push_back(
new G4VisAttributes(
true, G4Colour(1., 1., 0.)));
709 for (
const auto& epLayer : endplate.getEndPlateLayers()) {
710 const int iEPLayer = epLayer.getILayer();
711 const string name = epLayer.getName();
712 const double rmin = epLayer.getRmin();
713 const double rmax = epLayer.getRmax();
714 const double zbwd = epLayer.getZbwd();
715 const double zfwd = epLayer.getZfwd();
716 const double length = (zfwd - zbwd) / 2.0;
718 G4Tubs* tube =
new G4Tubs(
"solidCDCEndplate" + name, rmin * CLHEP::cm,
719 rmax * CLHEP::cm, length * CLHEP::cm, 0 * CLHEP::deg, 360.*CLHEP::deg);
720 G4LogicalVolume* logical =
new G4LogicalVolume(tube,
Materials::get(
"G4_Al"),
721 "logicalCDCEndplate" + name, 0, 0);
723 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (zfwd + zbwd)*CLHEP::cm / 2.0), logical,
724 "physicalCDCEndplate" + name,
m_logicalCDC,
false, iEPLayer);
733 const int iEB = frontend.getId();
734 const double ebInnerR = frontend.getRmin();
735 const double ebOuterR = frontend.getRmax();
736 const double ebBZ = frontend.getZbwd();
737 const double ebFZ = frontend.getZfwd();
739 G4Tubs* ebTubeShape =
new G4Tubs((boost::format(
"solidSD_ElectronicsBoard_Layer%1%") % iEB).str().c_str(), ebInnerR * CLHEP::cm,
740 ebOuterR * CLHEP::cm, (ebFZ - ebBZ)*CLHEP::cm / 2.0, 0 * CLHEP::deg, 360.*CLHEP::deg);
742 G4LogicalVolume* ebTube =
new G4LogicalVolume(ebTubeShape, medNEMA_G10_Plate,
743 (boost::format(
"logicalSD_ElectronicsBoard_Layer%1%") % iEB).str().c_str(), 0, 0, 0);
747 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (ebFZ + ebBZ)*CLHEP::cm / 2.0), ebTube,
748 (boost::format(
"physicalSD_ElectronicsBoard_Layer%1%") % iEB).str().c_str(),
m_logicalCDC,
false, iEB);
769 for (
const auto& rib : geo.
getRibs()) {
771 const int id = rib.getId();
772 const double length = rib.getLength();
773 const double width = rib.getWidth();
774 const double thick = rib.getThick();
775 const double rotx = rib.getRotX();
776 const double roty = rib.getRotY();
777 const double rotz = rib.getRotZ();
778 const double x = rib.getX();
779 const double y = rib.getY();
780 const double z = rib.getZ();
781 const int offset = rib.getOffset();
782 const int ndiv = rib.getNDiv();
784 const string solidName =
"solidRib" + to_string(
id);
785 const string logicalName =
"logicalRib" + to_string(
id);
786 G4Box* boxShape =
new G4Box(solidName, 0.5 * length * CLHEP::cm,
787 0.5 * width * CLHEP::cm,
788 0.5 * thick * CLHEP::cm);
790 const double rmax = 0.5 * length;
791 const double rmin = max((rmax - thick), 0.);
792 G4Tubs* tubeShape =
new G4Tubs(solidName,
795 0.5 * width * CLHEP::cm,
802 G4LogicalVolume* logicalV =
new G4LogicalVolume(boxShape, medAluminum, logicalName, 0, 0, 0);
803 if (
id > 39 &&
id < 78)
804 logicalV =
new G4LogicalVolume(boxShape, medCopper, logicalName, 0, 0, 0);
805 if ((
id > 77 &&
id < 94) || (
id > 131 &&
id < 146))
806 logicalV =
new G4LogicalVolume(boxShape, medNEMA_G10_Plate, logicalName, 0, 0, 0);
807 if (
id > 93 &&
id < 110)
808 logicalV =
new G4LogicalVolume(tubeShape, medCopper, logicalName, 0, 0, 0);
809 if (
id > 109 &&
id < 126)
810 logicalV =
new G4LogicalVolume(tubeShape, medH2O, logicalName, 0, 0, 0);
811 if (
id > 127 &&
id < 132)
812 logicalV =
new G4LogicalVolume(boxShape, medHV, logicalName, 0, 0, 0);
822 const double phi = 360.0 / ndiv;
824 G4RotationMatrix rot = G4RotationMatrix();
826 if (
id > 93 &&
id < 126) dz = 0;
828 G4ThreeVector arm(x * CLHEP::cm, y * CLHEP::cm, z * CLHEP::cm - dz * CLHEP::cm / 2.0);
833 rot.rotateZ(0.5 * phi * CLHEP::deg);
834 arm.rotateZ(0.5 * phi * CLHEP::deg);
836 for (
int i = 0; i < ndiv; ++i) {
837 const string physicalName =
"physicalRib_" + to_string(
id) +
" " + to_string(i);
838 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
840 rot.rotateZ(phi * CLHEP::deg);
841 arm.rotateZ(phi * CLHEP::deg);
849 for (
const auto& rib2 : geo.
getRib2s()) {
851 const int id = rib2.getId();
852 const double length = rib2.getLength();
853 const double width = rib2.getWidth();
854 const double thick = rib2.getThick();
855 const double width2 = rib2.getWidth2();
856 const double thick2 = rib2.getThick2();
857 const double rotx = rib2.getRotX();
858 const double roty = rib2.getRotY();
859 const double rotz = rib2.getRotZ();
860 const double x = rib2.getX();
861 const double y = rib2.getY();
862 const double z = rib2.getZ();
863 const int ndiv = rib2.getNDiv();
865 const string solidName =
"solidRib2" + to_string(
id);
866 const string logicalName =
"logicalRib2" + to_string(
id);
867 G4Trd* trdShape =
new G4Trd(solidName,
868 0.5 * thick * CLHEP::cm,
869 0.5 * thick2 * CLHEP::cm,
870 0.5 * width * CLHEP::cm,
871 0.5 * width2 * CLHEP::cm,
872 0.5 * length * CLHEP::cm);
874 G4LogicalVolume* logicalV =
new G4LogicalVolume(trdShape, medAluminum, logicalName, 0, 0, 0);
877 logicalV =
new G4LogicalVolume(trdShape, medCopper, logicalName, 0, 0, 0);
881 const double phi = 360.0 / ndiv;
883 G4RotationMatrix rot = G4RotationMatrix();
884 G4ThreeVector arm(x * CLHEP::cm, y * CLHEP::cm, z * CLHEP::cm - thick * CLHEP::cm / 2.0);
889 for (
int i = 0; i < ndiv; ++i) {
890 const string physicalName =
"physicalRib2_" + to_string(
id) +
" " + to_string(i);
891 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
893 rot.rotateZ(phi * CLHEP::deg);
894 arm.rotateZ(phi * CLHEP::deg);
902 for (
const auto& rib3 : geo.
getRib3s()) {
904 const int id = rib3.getId();
905 const double length = rib3.getLength();
906 const double width = rib3.getWidth();
907 const double thick = rib3.getThick();
908 const double r = rib3.getR();
909 const double x = rib3.getX();
910 const double y = rib3.getY();
911 const double z = rib3.getZ();
912 const double rx = rib3.getRx();
913 const double ry = rib3.getRy();
914 const double rz = rib3.getRz();
915 const int offset = rib3.getOffset();
916 const int ndiv = rib3.getNDiv();
918 const string logicalName =
"logicalRib3" + to_string(
id);
919 G4VSolid* boxShape =
new G4Box(
"Block",
920 0.5 * length * CLHEP::cm,
921 0.5 * width * CLHEP::cm,
922 0.5 * thick * CLHEP::cm);
923 G4VSolid* tubeShape =
new G4Tubs(
"Hole",
930 G4RotationMatrix rotsub = G4RotationMatrix();
931 rotsub.rotateX(90. * CLHEP::deg);
932 G4ThreeVector trnsub(rx * CLHEP::cm - x * CLHEP::cm, ry * CLHEP::cm - y * CLHEP::cm,
933 rz * CLHEP::cm - z * CLHEP::cm + 0.5 * thick * CLHEP::cm);
934 G4VSolid* coolingBlock =
new G4SubtractionSolid(
"Block-Hole",
937 G4Transform3D(rotsub,
940 G4LogicalVolume* logicalV =
new G4LogicalVolume(coolingBlock, medCopper, logicalName, 0, 0, 0);
944 const double phi = 360.0 / ndiv;
946 G4RotationMatrix rot = G4RotationMatrix();
947 G4ThreeVector arm(x * CLHEP::cm, y * CLHEP::cm, z * CLHEP::cm - thick * CLHEP::cm / 2.0);
950 rot.rotateZ(0.5 * phi * CLHEP::deg);
951 arm.rotateZ(0.5 * phi * CLHEP::deg);
953 for (
int i = 0; i < ndiv; ++i) {
954 const string physicalName =
"physicalRib3_" + to_string(
id) +
" " + to_string(i);
955 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
957 rot.rotateZ(phi * CLHEP::deg);
958 arm.rotateZ(phi * CLHEP::deg);
966 for (
const auto& rib4 : geo.
getRib4s()) {
968 const int id = rib4.getId();
969 const double length = rib4.getLength();
970 const double width = rib4.getWidth();
971 const double thick = rib4.getThick();
972 const double length2 = rib4.getLength2();
973 const double width2 = rib4.getWidth2();
974 const double thick2 = rib4.getThick2();
975 const double x = rib4.getX();
976 const double y = rib4.getY();
977 const double z = rib4.getZ();
978 const double x2 = rib4.getX2();
979 const double y2 = rib4.getY2();
980 const double z2 = rib4.getZ2();
981 const int offset = rib4.getOffset();
982 const int ndiv = rib4.getNDiv();
984 const string logicalName =
"logicalRib4" + to_string(
id);
985 G4VSolid* baseShape =
new G4Box(
"Base",
986 0.5 * length * CLHEP::cm,
987 0.5 * width * CLHEP::cm,
988 0.5 * thick * CLHEP::cm);
989 G4VSolid* sqShape =
new G4Box(
"Sq",
990 0.5 * length2 * CLHEP::cm,
991 0.5 * width2 * CLHEP::cm,
992 0.5 * thick2 * CLHEP::cm);
994 G4RotationMatrix rotsub = G4RotationMatrix();
995 double dzc = (z2 - thick2 / 2.) - (z - thick / 2.);
996 G4ThreeVector trnsub(x2 * CLHEP::cm - x * CLHEP::cm,
997 y2 * CLHEP::cm - y * CLHEP::cm,
999 G4VSolid* sqHoleBase =
new G4SubtractionSolid(
"Box-Sq",
1002 G4Transform3D(rotsub,
1006 G4LogicalVolume* logicalV =
new G4LogicalVolume(sqHoleBase, medCopper, logicalName, 0, 0, 0);
1008 logicalV =
new G4LogicalVolume(sqHoleBase, medNEMA_G10_Plate, logicalName, 0, 0, 0);
1014 const double phi = 360.0 / ndiv;
1016 G4RotationMatrix rot = G4RotationMatrix();
1017 G4ThreeVector arm(x * CLHEP::cm, y * CLHEP::cm, z * CLHEP::cm - thick * CLHEP::cm / 2.0);
1020 rot.rotateZ(0.5 * phi * CLHEP::deg);
1021 arm.rotateZ(0.5 * phi * CLHEP::deg);
1023 for (
int i = 0; i < ndiv; ++i) {
1024 const string physicalName =
"physicalRib4_" + to_string(
id) +
" " + to_string(i);
1025 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
1027 rot.rotateZ(phi * CLHEP::deg);
1028 arm.rotateZ(phi * CLHEP::deg);
1035 for (
const auto& rib5 : geo.
getRib5s()) {
1037 const int id = rib5.getId();
1038 const double dr = rib5.getDr();
1039 const double dz = rib5.getDz();
1040 const double width = rib5.getWidth();
1041 const double thick = rib5.getThick();
1042 const double rin = rib5.getRin();
1043 const double x = rib5.getX();
1044 const double y = rib5.getY();
1045 const double z = rib5.getZ();
1046 const double rotx = rib5.getRotx();
1047 const double roty = rib5.getRoty();
1048 const double rotz = rib5.getRotz();
1049 const int offset = rib5.getOffset();
1050 const int ndiv = rib5.getNDiv();
1052 const string solidName =
"solidRib5" + to_string(
id);
1053 const string logicalName =
"logicalRib5" + to_string(
id);
1055 const double rmax = rin + thick;
1056 const double rmin = rin;
1057 const double dphi = 2. * atan2(dz, dr);
1058 const double ddphi = thick * tan(dphi) / rin;
1059 const double ddphi2 = width / 2. * width / 2. / (x + dr) / rin;
1060 const double cphi = dphi - ddphi - ddphi2;
1061 G4Tubs* tubeShape =
new G4Tubs(solidName,
1064 0.5 * width * CLHEP::cm,
1068 G4LogicalVolume* logicalV =
new G4LogicalVolume(tubeShape, medAluminum, logicalName, 0, 0, 0);
1072 const double phi = 360.0 / ndiv;
1074 G4RotationMatrix rot = G4RotationMatrix();
1077 G4ThreeVector arm(x * CLHEP::cm, y * CLHEP::cm, z * CLHEP::cm - rin * CLHEP::cm - thick * CLHEP::cm);
1082 rot.rotateZ(0.5 * phi * CLHEP::deg);
1083 arm.rotateZ(0.5 * phi * CLHEP::deg);
1085 for (
int i = 0; i < ndiv; ++i) {
1086 const string physicalName =
"physicalRib5_" + to_string(
id) +
" " + to_string(i);
1087 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
1089 rot.rotateZ(phi * CLHEP::deg);
1090 arm.rotateZ(phi * CLHEP::deg);
1108 G4Material* boratedpoly05 =
new G4Material(
"BoratedPoly05", 1.06 * CLHEP::g / CLHEP::cm3, 2);
1109 boratedpoly05->AddMaterial(elB, 0.05);
1110 boratedpoly05->AddMaterial(C2H4, 0.95);
1112 G4Material* boratedpoly30 =
new G4Material(
"BoratedPoly30", 1.19 * CLHEP::g / CLHEP::cm3, 2);
1113 boratedpoly30->AddMaterial(elB, 0.30);
1114 boratedpoly30->AddMaterial(C2H4, 0.70);
1116 G4Material* shieldMat = C2H4;
1118 const int nShields = content.getNumberNodes(
"Shields/Shield");
1120 for (
int iShield = 0; iShield < nShields; ++iShield) {
1121 GearDir shieldContent(content);
1122 shieldContent.
append((boost::format(
"/Shields/Shield[%1%]/") % (iShield + 1)).str());
1123 const string sShieldID = shieldContent.
getString(
"@id");
1124 const int shieldID = atoi(sShieldID.c_str());
1126 const double shieldInnerR1 = shieldContent.
getLength(
"InnerR1");
1127 const double shieldInnerR2 = shieldContent.
getLength(
"InnerR2");
1128 const double shieldOuterR1 = shieldContent.
getLength(
"OuterR1");
1129 const double shieldOuterR2 = shieldContent.
getLength(
"OuterR2");
1130 const double shieldThick = shieldContent.
getLength(
"Thickness");
1131 const double shieldPosZ = shieldContent.
getLength(
"PosZ");
1133 G4Cons* shieldConsShape =
new G4Cons((boost::format(
"solidShield%1%") % shieldID).str().c_str(),
1134 shieldInnerR1 * CLHEP::cm, shieldOuterR1 * CLHEP::cm,
1135 shieldInnerR2 * CLHEP::cm, shieldOuterR2 * CLHEP::cm,
1136 shieldThick * CLHEP::cm / 2.0,
1137 0.*CLHEP::deg, 360.*CLHEP::deg);
1139 G4LogicalVolume* shieldCons =
new G4LogicalVolume(shieldConsShape, shieldMat,
1140 (boost::format(
"logicalShield%1%") % shieldID).str().c_str(),
1143 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (shieldPosZ - shieldThick / 2.0) * CLHEP::cm), shieldCons,
1144 (boost::format(
"physicalShield%1%") % shieldID).str().c_str(),
m_logicalCDC,
false, 0);
1155 G4Material* shieldMat = C2H4;
1157 for (
const auto& shield : geom.getNeutronShields()) {
1158 const int shieldID = shield.getId();
1159 const double shieldInnerR1 = shield.getRmin1();
1160 const double shieldInnerR2 = shield.getRmin2();
1161 const double shieldOuterR1 = shield.getRmax1();
1162 const double shieldOuterR2 = shield.getRmax2();
1163 const double shieldThick = shield.getThick();
1164 const double shieldPosZ = shield.getZ();
1166 G4Cons* shieldConsShape =
new G4Cons(
"solidShield" + to_string(shieldID),
1167 shieldInnerR1 * CLHEP::cm, shieldOuterR1 * CLHEP::cm,
1168 shieldInnerR2 * CLHEP::cm, shieldOuterR2 * CLHEP::cm,
1169 shieldThick * CLHEP::cm / 2.0,
1170 0.*CLHEP::deg, 360.*CLHEP::deg);
1172 G4LogicalVolume* shieldCons =
new G4LogicalVolume(shieldConsShape, shieldMat,
"logicalShield" + to_string(shieldID),
1175 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, (shieldPosZ - shieldThick / 2.0) * CLHEP::cm), shieldCons,
1176 "physicalShield" + to_string(shieldID),
m_logicalCDC,
false, 0);
1184 string Aluminum = content.getString(
"Aluminum");
1187 G4double density = 1.000 * CLHEP::g / CLHEP::cm3;
1188 G4double a = 1.01 * CLHEP::g / CLHEP::mole;
1189 G4Element* elH =
new G4Element(
"Hydrogen",
"H", 1., a);
1190 a = 16.00 * CLHEP::g / CLHEP::mole;
1191 G4Element* elO =
new G4Element(
"Oxygen",
"O", 8., a);
1192 G4Material* medH2O =
new G4Material(
"Water", density, 2);
1193 medH2O->AddElement(elH, 2);
1194 medH2O->AddElement(elO, 1);
1202 m_VisAttributes.push_back(
new G4VisAttributes(
true, G4Colour(0., 1., 0.)));
1203 const int nCover = content.getNumberNodes(
"Covers/Cover");
1204 for (
int iCover = 0; iCover < nCover; ++iCover) {
1205 GearDir coverContent(content);
1206 coverContent.
append((boost::format(
"/Covers/Cover[%1%]/") % (iCover + 1)).str());
1207 const string scoverID = coverContent.
getString(
"@id");
1208 const int coverID = atoi(scoverID.c_str());
1209 const string coverName = coverContent.
getString(
"Name");
1210 const double coverInnerR1 = coverContent.
getLength(
"InnerR1");
1211 const double coverInnerR2 = coverContent.
getLength(
"InnerR2");
1212 const double coverOuterR1 = coverContent.
getLength(
"OuterR1");
1213 const double coverOuterR2 = coverContent.
getLength(
"OuterR2");
1214 const double coverThick = coverContent.
getLength(
"Thickness");
1215 const double coverPosZ = coverContent.
getLength(
"PosZ");
1217 const double rmin1 = coverInnerR1;
1218 const double rmax1 = coverOuterR1;
1219 const double rmin2 = coverInnerR2;
1220 const double rmax2 = coverOuterR2;
1231 if (coverID == 7 || coverID == 10) {
1232 createCone(rmin1, rmax1, rmin2, rmax2, coverThick, coverPosZ, coverID, medAluminum, coverName);
1234 createTube(rmin1, rmax1, coverThick, coverPosZ, coverID, medAluminum, coverName);
1237 if (coverID > 22 && coverID < 29)
1238 createTube(rmin1, rmax1, coverThick, coverPosZ, coverID, medCopper, coverName);
1239 if (coverID > 28 && coverID < 35)
1240 createTorus(rmin1, rmax1, coverThick, coverPosZ, coverID, medCopper, coverName);
1241 if (coverID > 34 && coverID < 41)
1242 createTorus(rmin1, rmax1, coverThick, coverPosZ, coverID, medH2O, coverName);
1243 if (coverID == 45 || coverID == 46)
1244 createTube(rmin1, rmax1, coverThick, coverPosZ, coverID, medLV, coverName);
1245 if (coverID == 47 || coverID == 48)
1246 createTube(rmin1, rmax1, coverThick, coverPosZ, coverID, medFiber, coverName);
1247 if (coverID == 49 || coverID == 50)
1248 createTube(rmin1, rmax1, coverThick, coverPosZ, coverID, medCAT7, coverName);
1249 if (coverID == 51 || coverID == 52)
1250 createTube(rmin1, rmax1, coverThick, coverPosZ, coverID, medTRG, coverName);
1252 createTube(rmin1, rmax1, coverThick, coverPosZ, coverID, medHV, coverName);
1255 const int nCover2 = content.getNumberNodes(
"Covers/Cover2");
1256 for (
int iCover2 = 0; iCover2 < nCover2; ++iCover2) {
1257 GearDir cover2Content(content);
1258 cover2Content.
append((boost::format(
"/Cover2s/Cover2[%1%]/") % (iCover2 + 1)).str());
1259 const string scover2ID = cover2Content.
getString(
"@id");
1260 const int cover2ID = atoi(scover2ID.c_str());
1261 const string cover2Name = cover2Content.
getString(
"Name");
1262 const double cover2InnerR = cover2Content.
getLength(
"InnerR");
1263 const double cover2OuterR = cover2Content.
getLength(
"OuterR");
1264 const double cover2StartPhi = cover2Content.
getLength(
"StartPhi");
1265 const double cover2DeltaPhi = cover2Content.
getLength(
"DeltaPhi");
1266 const double cover2Thick = cover2Content.
getLength(
"Thickness");
1267 const double cover2PosZ = cover2Content.
getLength(
"PosZ");
1270 createTube2(cover2InnerR, cover2OuterR, cover2StartPhi, cover2DeltaPhi, cover2Thick, cover2PosZ, cover2ID, medHV, cover2Name);
1271 if (cover2ID > 10 && cover2ID < 14)
1272 createTube2(cover2InnerR, cover2OuterR, cover2StartPhi, cover2DeltaPhi, cover2Thick, cover2PosZ, cover2ID, medFiber, cover2Name);
1273 if (cover2ID > 13 && cover2ID < 23)
1274 createTube2(cover2InnerR, cover2OuterR, cover2StartPhi, cover2DeltaPhi, cover2Thick, cover2PosZ, cover2ID, medCAT7, cover2Name);
1275 if (cover2ID > 22 && cover2ID < 29)
1276 createTube2(cover2InnerR, cover2OuterR, cover2StartPhi, cover2DeltaPhi, cover2Thick, cover2PosZ, cover2ID, medTRG, cover2Name);
1279 const int nRibs = content.getNumberNodes(
"Covers/Rib");
1280 for (
int iRib = 0; iRib < nRibs; ++iRib) {
1282 ribContent.
append((boost::format(
"/Covers/Rib[%1%]/") % (iRib + 1)).str());
1283 const string sribID = ribContent.
getString(
"@id");
1284 const int ribID = atoi(sribID.c_str());
1286 const double length = ribContent.
getLength(
"Length");
1287 const double width = ribContent.
getLength(
"Width");
1288 const double thick = ribContent.
getLength(
"Thickness");
1289 const double rotX = ribContent.
getLength(
"RotX");
1290 const double rotY = ribContent.
getLength(
"RotY");
1291 const double rotZ = ribContent.
getLength(
"RotZ");
1292 const double cX = ribContent.
getLength(
"PosX");
1293 const double cY = ribContent.
getLength(
"PosY");
1294 const double cZ = ribContent.
getLength(
"PosZ");
1295 const int offset = atoi((ribContent.
getString(
"Offset")).c_str());
1296 const int number = atoi((ribContent.
getString(
"NDiv")).c_str());
1298 const string solidName =
"solidRib" + to_string(ribID);
1299 const string logicalName =
"logicalRib" + to_string(ribID);
1300 G4Box* boxShape =
new G4Box(solidName, 0.5 * length * CLHEP::cm,
1301 0.5 * width * CLHEP::cm,
1302 0.5 * thick * CLHEP::cm);
1303 const double rmax = 0.5 * length;
1304 const double rmin = max((rmax - thick), 0.);
1305 G4Tubs* tubeShape =
new G4Tubs(solidName,
1308 0.5 * width * CLHEP::cm,
1315 G4LogicalVolume* logicalV =
new G4LogicalVolume(boxShape, medAluminum, logicalName, 0, 0, 0);
1316 if (ribID > 39 && ribID < 78)
1317 logicalV =
new G4LogicalVolume(boxShape, medCopper, logicalName, 0, 0, 0);
1318 if ((ribID > 77 && ribID < 94) || (ribID > 131 && ribID < 146))
1319 logicalV =
new G4LogicalVolume(boxShape, medNEMA_G10_Plate, logicalName, 0, 0, 0);
1320 if (ribID > 93 && ribID < 110)
1321 logicalV =
new G4LogicalVolume(tubeShape, medCopper, logicalName, 0, 0, 0);
1322 if (ribID > 109 && ribID < 126)
1323 logicalV =
new G4LogicalVolume(tubeShape, medH2O, logicalName, 0, 0, 0);
1324 if (ribID > 127 && ribID < 132)
1325 logicalV =
new G4LogicalVolume(boxShape, medHV, logicalName, 0, 0, 0);
1335 const double phi = 360.0 / number;
1337 G4RotationMatrix rot = G4RotationMatrix();
1340 if (ribID > 93 && ribID < 126) dz = 0;
1341 G4ThreeVector arm(cX * CLHEP::cm, cY * CLHEP::cm, cZ * CLHEP::cm - dz * CLHEP::cm / 2.0);
1347 rot.rotateZ(0.5 * phi * CLHEP::deg);
1348 arm.rotateZ(0.5 * phi * CLHEP::deg);
1350 for (
int i = 0; i < number; ++i) {
1351 const string physicalName =
"physicalRib_" + to_string(ribID) +
" " + to_string(i);
1352 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
1354 rot.rotateZ(phi * CLHEP::deg);
1355 arm.rotateZ(phi * CLHEP::deg);
1360 const int nRib2s = content.getNumberNodes(
"Covers/Rib2");
1361 for (
int iRib2 = 0; iRib2 < nRib2s; ++iRib2) {
1363 rib2Content.
append((boost::format(
"/Covers/Rib2[%1%]/") % (iRib2 + 1)).str());
1364 const string srib2ID = rib2Content.
getString(
"@id");
1365 const int rib2ID = atoi(srib2ID.c_str());
1367 const double length = rib2Content.
getLength(
"Length");
1368 const double width = rib2Content.
getLength(
"Width");
1369 const double thick = rib2Content.
getLength(
"Thickness");
1370 const double width2 = rib2Content.
getLength(
"Width2");
1371 const double thick2 = rib2Content.
getLength(
"Thickness2");
1372 const double rotX = rib2Content.
getLength(
"RotX");
1373 const double rotY = rib2Content.
getLength(
"RotY");
1374 const double rotZ = rib2Content.
getLength(
"RotZ");
1375 const double cX = rib2Content.
getLength(
"PosX");
1376 const double cY = rib2Content.
getLength(
"PosY");
1377 const double cZ = rib2Content.
getLength(
"PosZ");
1378 const int number = atoi((rib2Content.
getString(
"NDiv")).c_str());
1380 const string solidName =
"solidRib2" + to_string(rib2ID);
1381 const string logicalName =
"logicalRib2" + to_string(rib2ID);
1382 G4Trd* trdShape =
new G4Trd(solidName,
1383 0.5 * thick * CLHEP::cm,
1384 0.5 * thick2 * CLHEP::cm,
1385 0.5 * width * CLHEP::cm,
1386 0.5 * width2 * CLHEP::cm,
1387 0.5 * length * CLHEP::cm);
1389 G4LogicalVolume* logicalV =
new G4LogicalVolume(trdShape, medAluminum, logicalName, 0, 0, 0);
1391 logicalV =
new G4LogicalVolume(trdShape, medCopper, logicalName, 0, 0, 0);
1395 const double phi = 360.0 / number;
1397 G4RotationMatrix rot = G4RotationMatrix();
1398 G4ThreeVector arm(cX * CLHEP::cm, cY * CLHEP::cm, cZ * CLHEP::cm - thick * CLHEP::cm / 2.0);
1403 for (
int i = 0; i < number; ++i) {
1404 const string physicalName =
"physicalRib2_" + to_string(rib2ID) +
" " + to_string(i);
1405 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
1407 rot.rotateZ(phi * CLHEP::deg);
1408 arm.rotateZ(phi * CLHEP::deg);
1413 const int nRib3s = content.getNumberNodes(
"Covers/Rib3");
1414 for (
int iRib3 = 0; iRib3 < nRib3s; ++iRib3) {
1416 rib3Content.
append((boost::format(
"/Covers/Rib3[%1%]/") % (iRib3 + 1)).str());
1417 const string srib3ID = rib3Content.
getString(
"@id");
1418 const int rib3ID = atoi(srib3ID.c_str());
1420 const double length = rib3Content.
getLength(
"Length");
1421 const double width = rib3Content.
getLength(
"Width");
1422 const double thick = rib3Content.
getLength(
"Thickness");
1423 const double r = rib3Content.
getLength(
"HoleR");
1424 const double cX = rib3Content.
getLength(
"PosX");
1425 const double cY = rib3Content.
getLength(
"PosY");
1426 const double cZ = rib3Content.
getLength(
"PosZ");
1427 const double hX = rib3Content.
getLength(
"HoleX");
1428 const double hY = rib3Content.
getLength(
"HoleY");
1429 const double hZ = rib3Content.
getLength(
"HoleZ");
1430 const int offset = atoi((rib3Content.
getString(
"Offset")).c_str());
1431 const int number = atoi((rib3Content.
getString(
"NDiv")).c_str());
1433 const string logicalName =
"logicalRib3" + to_string(rib3ID);
1434 G4VSolid* boxShape =
new G4Box(
"Block",
1435 0.5 * length * CLHEP::cm,
1436 0.5 * width * CLHEP::cm,
1437 0.5 * thick * CLHEP::cm);
1438 G4VSolid* tubeShape =
new G4Tubs(
"Hole",
1444 G4RotationMatrix rotsub = G4RotationMatrix();
1445 G4ThreeVector trnsub(cX * CLHEP::cm - hX * CLHEP::cm, cY * CLHEP::cm - hY * CLHEP::cm,
1446 cZ * CLHEP::cm - hZ * CLHEP::cm + 0.5 * thick * CLHEP::cm);
1447 G4VSolid* coolingBlock =
new G4SubtractionSolid(
"Block-Hole",
1450 G4Transform3D(rotsub,
1453 G4LogicalVolume* logicalV =
new G4LogicalVolume(coolingBlock, medCopper, logicalName, 0, 0, 0);
1457 const double phi = 360.0 / number;
1459 G4RotationMatrix rot = G4RotationMatrix();
1460 G4ThreeVector arm(cX * CLHEP::cm, cY * CLHEP::cm, cZ * CLHEP::cm - thick * CLHEP::cm / 2.0);
1463 rot.rotateZ(0.5 * phi * CLHEP::deg);
1464 arm.rotateZ(0.5 * phi * CLHEP::deg);
1466 for (
int i = 0; i < number; ++i) {
1467 const string physicalName =
"physicalRib3_" + to_string(rib3ID) +
" " + to_string(i);
1468 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
1470 rot.rotateZ(phi * CLHEP::deg);
1471 arm.rotateZ(phi * CLHEP::deg);
1476 const int nRib4s = content.getNumberNodes(
"Covers/Rib4");
1477 for (
int iRib4 = 0; iRib4 < nRib4s; ++iRib4) {
1479 rib4Content.
append((boost::format(
"/Covers/Rib4[%1%]/") % (iRib4 + 1)).str());
1480 const string srib4ID = rib4Content.
getString(
"@id");
1481 const int rib4ID = atoi(srib4ID.c_str());
1483 const double length = rib4Content.
getLength(
"Length");
1484 const double width = rib4Content.
getLength(
"Width");
1485 const double thick = rib4Content.
getLength(
"Thickness");
1486 const double length2 = rib4Content.
getLength(
"Length2");
1487 const double width2 = rib4Content.
getLength(
"Width2");
1488 const double thick2 = rib4Content.
getLength(
"Thickness2");
1489 const double cX = rib4Content.
getLength(
"PosX");
1490 const double cY = rib4Content.
getLength(
"PosY");
1491 const double cZ = rib4Content.
getLength(
"PosZ");
1492 const double hX = rib4Content.
getLength(
"HoleX");
1493 const double hY = rib4Content.
getLength(
"HoleY");
1494 const double hZ = rib4Content.
getLength(
"HoleZ");
1495 const int offset = atoi((rib4Content.
getString(
"Offset")).c_str());
1496 const int number = atoi((rib4Content.
getString(
"NDiv")).c_str());
1498 const string logicalName =
"logicalRib4" + to_string(rib4ID);
1499 G4VSolid* baseShape =
new G4Box(
"Base",
1500 0.5 * length * CLHEP::cm,
1501 0.5 * width * CLHEP::cm,
1502 0.5 * thick * CLHEP::cm);
1503 G4VSolid* sqShape =
new G4Box(
"Sq",
1504 0.5 * length2 * CLHEP::cm,
1505 0.5 * width2 * CLHEP::cm,
1506 0.5 * thick2 * CLHEP::cm);
1507 G4RotationMatrix rotsub = G4RotationMatrix();
1508 double dzc = (hZ - thick2 / 2.) - (cZ - thick / 2.);
1509 G4ThreeVector trnsub(hX * CLHEP::cm - cX * CLHEP::cm,
1510 hY * CLHEP::cm - cY * CLHEP::cm,
1512 G4VSolid* sqHoleBase =
new G4SubtractionSolid(
"Base-Sq",
1515 G4Transform3D(rotsub,
1519 G4LogicalVolume* logicalV =
new G4LogicalVolume(sqHoleBase, medCopper, logicalName, 0, 0, 0);
1521 logicalV =
new G4LogicalVolume(sqHoleBase, medNEMA_G10_Plate, logicalName, 0, 0, 0);
1525 const double phi = 360.0 / number;
1527 G4RotationMatrix rot = G4RotationMatrix();
1528 G4ThreeVector arm(cX * CLHEP::cm, cY * CLHEP::cm, cZ * CLHEP::cm - thick * CLHEP::cm / 2.0);
1531 rot.rotateZ(0.5 * phi * CLHEP::deg);
1532 arm.rotateZ(0.5 * phi * CLHEP::deg);
1534 for (
int i = 0; i < number; ++i) {
1535 const string physicalName =
"physicalRib4_" + to_string(rib4ID) +
" " + to_string(i);
1536 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
1538 rot.rotateZ(phi * CLHEP::deg);
1539 arm.rotateZ(phi * CLHEP::deg);
1544 const int nRib5s = content.getNumberNodes(
"Covers/Rib5");
1545 for (
int iRib5 = 0; iRib5 < nRib5s; ++iRib5) {
1547 rib5Content.
append((boost::format(
"/Covers/Rib5[%1%]/") % (iRib5 + 1)).str());
1548 const string srib5ID = rib5Content.
getString(
"@id");
1549 const int rib5ID = atoi(srib5ID.c_str());
1551 const double dr = rib5Content.
getLength(
"DeltaR");
1552 const double dz = rib5Content.
getLength(
"DeltaZ");
1553 const double width = rib5Content.
getLength(
"Width");
1554 const double thick = rib5Content.
getLength(
"Thickness");
1555 const double rin = rib5Content.
getLength(
"Rin");
1556 const double rotX = rib5Content.
getLength(
"RotX");
1557 const double rotY = rib5Content.
getLength(
"RotY");
1558 const double rotZ = rib5Content.
getLength(
"RotZ");
1559 const double cX = rib5Content.
getLength(
"PosX");
1560 const double cY = rib5Content.
getLength(
"PosY");
1561 const double cZ = rib5Content.
getLength(
"PosZ");
1562 const int offset = atoi((rib5Content.
getString(
"Offset")).c_str());
1563 const int number = atoi((rib5Content.
getString(
"NDiv")).c_str());
1565 const string solidName =
"solidRib5" + to_string(rib5ID);
1566 const string logicalName =
"logicalRib5" + to_string(rib5ID);
1567 const double rmax = rin + thick;
1568 const double rmin = rin;
1569 const double dphi = 2. * atan2(dz, dr);
1570 const double ddphi = thick * tan(dphi) / rin;
1571 const double ddphi2 = width / 2. * width / 2. / (cX + dr) / rin;
1572 const double cphi = dphi - ddphi - ddphi2;
1573 G4Tubs* tubeShape =
new G4Tubs(solidName,
1576 0.5 * width * CLHEP::cm,
1580 G4LogicalVolume* logicalV =
new G4LogicalVolume(tubeShape, medAluminum, logicalName, 0, 0, 0);
1584 const double phi = 360.0 / number;
1586 G4RotationMatrix rot = G4RotationMatrix();
1589 G4ThreeVector arm(cX * CLHEP::cm, cY * CLHEP::cm, cZ * CLHEP::cm - rin * CLHEP::cm - thick * CLHEP::cm);
1595 rot.rotateZ(0.5 * phi * CLHEP::deg);
1596 arm.rotateZ(0.5 * phi * CLHEP::deg);
1598 for (
int i = 0; i < number; ++i) {
1599 const string physicalName =
"physicalRib5_" + to_string(rib5ID) +
" " + to_string(i);
1600 new G4PVPlacement(G4Transform3D(rot, arm), logicalV,
1602 rot.rotateZ(phi * CLHEP::deg);
1603 arm.rotateZ(phi * CLHEP::deg);
1613 G4double density = 1.000 * CLHEP::g / CLHEP::cm3;
1614 G4double a = 1.01 * CLHEP::g / CLHEP::mole;
1615 G4Element* elH =
new G4Element(
"Hydrogen",
"H", 1., a);
1616 a = 16.00 * CLHEP::g / CLHEP::mole;
1617 G4Element* elO =
new G4Element(
"Oxygen",
"O", 8., a);
1618 G4Material* medH2O =
new G4Material(
"water", density, 2);
1619 medH2O->AddElement(elH, 2);
1620 medH2O->AddElement(elO, 1);
1628 m_VisAttributes.push_back(
new G4VisAttributes(
true, G4Colour(0., 1., 0.)));
1629 for (
const auto& cover : geom.getCovers()) {
1630 const int coverID = cover.getId();
1631 const string coverName =
"cover" + to_string(coverID);
1632 const double rmin1 = cover.getRmin1();
1633 const double rmin2 = cover.getRmin2();
1634 const double rmax1 = cover.getRmax1();
1635 const double rmax2 = cover.getRmax2();
1636 const double thick = cover.getThick();
1637 const double posZ = cover.getZ();
1646 if (coverID == 7 || coverID == 10) {
1647 createCone(rmin1, rmax1, rmin2, rmax2, thick, posZ, coverID, medAl, coverName);
1649 createTube(rmin1, rmax1, thick, posZ, coverID, medAl, coverName);
1652 if (coverID > 22 && coverID < 29)
1653 createTube(rmin1, rmax1, thick, posZ, coverID, medCu, coverName);
1654 if (coverID > 28 && coverID < 35)
1655 createTorus(rmin1, rmax1, thick, posZ, coverID, medCu, coverName);
1656 if (coverID > 34 && coverID < 41)
1657 createTorus(rmin1, rmax1, thick, posZ, coverID, medH2O, coverName);
1658 if (coverID == 45 || coverID == 46)
1659 createTube(rmin1, rmax1, thick, posZ, coverID, medLV, coverName);
1660 if (coverID == 47 || coverID == 48)
1661 createTube(rmin1, rmax1, thick, posZ, coverID, medFiber, coverName);
1662 if (coverID == 49 || coverID == 50)
1663 createTube(rmin1, rmax1, thick, posZ, coverID, medCAT7, coverName);
1664 if (coverID == 51 || coverID == 52)
1665 createTube(rmin1, rmax1, thick, posZ, coverID, medTRG, coverName);
1667 createTube(rmin1, rmax1, thick, posZ, coverID, medHV, coverName);
1678 m_VisAttributes.push_back(
new G4VisAttributes(
true, G4Colour(0., 1., 0.)));
1679 for (
const auto& cover2 : geom.getCover2s()) {
1680 const int cover2ID = cover2.getId();
1681 const string cover2Name =
"cover2" + to_string(cover2ID);
1682 const double rmin = cover2.getRmin();
1683 const double rmax = cover2.getRmax();
1684 const double phis = cover2.getPhis();
1685 const double dphi = cover2.getDphi();
1686 const double thick = cover2.getThick();
1687 const double posZ = cover2.getZ();
1690 createTube2(rmin, rmax, phis, dphi, thick, posZ, cover2ID, medHV, cover2Name);
1691 if (cover2ID > 10 && cover2ID < 14)
1692 createTube2(rmin, rmax, phis, dphi, thick, posZ, cover2ID, medFiber, cover2Name);
1693 if (cover2ID > 13 && cover2ID < 23)
1694 createTube2(rmin, rmax, phis, dphi, thick, posZ, cover2ID, medCAT7, cover2Name);
1695 if (cover2ID > 22 && cover2ID < 29)
1696 createTube2(rmin, rmax, phis, dphi, thick, posZ, cover2ID, medTRG, cover2Name);
1701 const double rmin2,
const double rmax2,
1702 const double thick,
const double posZ,
1703 const int id, G4Material* med,
1706 const string solidName =
"solid" + name;
1707 const string logicalName =
"logical" + name;
1708 const string physicalName =
"physical" + name;
1709 G4Cons* coverConeShape =
new G4Cons(solidName.c_str(), rmin1 * CLHEP::cm, rmax1 * CLHEP::cm,
1710 rmin2 * CLHEP::cm, rmax2 * CLHEP::cm, thick * CLHEP::cm / 2.0, 0.*CLHEP::deg, 360.*CLHEP::deg);
1711 G4LogicalVolume* coverCone =
new G4LogicalVolume(coverConeShape, med,
1712 logicalName.c_str(), 0, 0, 0);
1714 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, posZ * CLHEP::cm - thick * CLHEP::cm / 2.0), coverCone,
1720 const double thick,
const double posZ,
1721 const int id, G4Material* med,
1724 const string solidName =
"solid" + name;
1725 const string logicalName =
"logical" + name;
1726 const string physicalName =
"physical" + name;
1727 G4Tubs* solidV =
new G4Tubs(solidName.c_str(),
1730 thick * CLHEP::cm / 2.0,
1733 G4LogicalVolume* logicalV =
new G4LogicalVolume(solidV, med,
1734 logicalName.c_str(), 0, 0, 0);
1736 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, posZ * CLHEP::cm - thick * CLHEP::cm / 2.0), logicalV,
1742 const double thick,
const double x,
1743 const double y,
const double z,
1744 const int id, G4Material* med,
1747 const string solidName = (boost::format(
"solid%1%%2%") % name % id).str();
1748 const string logicalName = (boost::format(
"logical%1%%2%") % name % id).str();
1749 const string physicalName = (boost::format(
"physical%1%%2%") % name % id).str();
1750 G4Box* boxShape =
new G4Box(solidName.c_str(), 0.5 * length * CLHEP::cm,
1751 0.5 * height * CLHEP::cm,
1752 0.5 * thick * CLHEP::cm);
1753 G4LogicalVolume* logicalV =
new G4LogicalVolume(boxShape, med,
1754 logicalName.c_str(), 0, 0, 0);
1756 new G4PVPlacement(0, G4ThreeVector(x * CLHEP::cm, y * CLHEP::cm, z * CLHEP::cm - thick * CLHEP::cm / 2.0), logicalV,
1762 const double thick,
const double posZ,
1763 const int id, G4Material* med,
1766 const string solidName =
"solid" + name;
1767 const string logicalName =
"logical" + name;
1768 const string physicalName =
"physical" + name;
1769 const double rtor = (rmax1 + rmin1) / 2.;
1770 const double rmax = rmax1 - rtor;
1771 const double rmin = max((rmax - thick), 0.);
1773 G4Torus* solidV =
new G4Torus(solidName.c_str(),
1779 G4LogicalVolume* logicalV =
new G4LogicalVolume(solidV, med,
1780 logicalName.c_str(), 0, 0, 0);
1782 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, posZ * CLHEP::cm), logicalV,
1788 const double phis,
const double phie,
1789 const double thick,
const double posZ,
1790 const int id, G4Material* med,
1793 const string solidName =
"solid" + name;
1794 const string logicalName =
"logical" + name;
1795 const string physicalName =
"physical" + name;
1796 G4Tubs* solidV =
new G4Tubs(solidName.c_str(),
1799 thick * CLHEP::cm / 2.0,
1802 G4LogicalVolume* logicalV =
new G4LogicalVolume(solidV, med,
1803 logicalName.c_str(), 0, 0, 0);
1805 new G4PVPlacement(0, G4ThreeVector(0.0, 0.0, posZ * CLHEP::cm - thick * CLHEP::cm / 2.0), logicalV,
1815 const double xc = 0.5 * (-0.0002769 + 0.0370499) * CLHEP::cm;
1816 const double yc = 0.5 * (-0.0615404 + -0.108948) * CLHEP::cm;
1817 const double zc = 0.5 * (-35.3 + 48.5) * CLHEP::cm;
1822 const double plateWidth = 13.8 * CLHEP::cm;
1823 const double plateThick = 1.2 * CLHEP::cm;
1824 const double plateLength = 83.8 * CLHEP::cm;
1830 const double endPlateRmin = 4.0 * CLHEP::cm;
1831 const double endPlateRmax = 15.5 * CLHEP::cm;
1832 const double bwdEndPlateThick = 1.7 * CLHEP::cm;
1833 const double fwdEndPlateThick = 2.0 * CLHEP::cm;
1837 string name =
"Plate";
1839 G4Box* plateShape =
new G4Box(
"solid" + name, .5 * plateWidth, .5 * plateThick, .5 * plateLength);
1840 G4LogicalVolume* logical0 =
new G4LogicalVolume(plateShape, medAluminum,
"logical" + name, 0, 0, 0);
1843 const double x = xc + 0.5 * plateWidth;
1845 const double y = yc + endPlateRmin + 0.1 * CLHEP::cm;
1847 G4ThreeVector xyz(x, y, zc);
1848 G4RotationMatrix rotM3 = G4RotationMatrix();
1851 new G4PVPlacement(G4Transform3D(rotM3, xyz), logical0,
"physical" + name, &topVolume,
false, pID);
1853 const double alf = 120. * CLHEP::deg;
1856 new G4PVPlacement(G4Transform3D(rotM3, xyz), logical0,
"physical" + name, &topVolume,
false, pID + 1);
1860 new G4PVPlacement(G4Transform3D(rotM3, xyz), logical0,
"physical" + name, &topVolume,
false, pID + 2);
1864 name =
"BwdEndPlate";
1865 G4Tubs* BwdEndPlateShape =
new G4Tubs(
"solid" + name, endPlateRmin, endPlateRmax, 0.5 * bwdEndPlateThick, 0., 360.*CLHEP::deg);
1866 G4LogicalVolume* logical1 =
new G4LogicalVolume(BwdEndPlateShape, medAluminum,
"logical" + name, 0, 0, 0);
1869 double z = -35.3 * CLHEP::cm - 0.5 * bwdEndPlateThick;
1871 new G4PVPlacement(0, G4ThreeVector(xc, yc, z), logical1,
"physical" + name, &topVolume,
false, pID);
1876 name =
"FwdEndPlate";
1877 G4Tubs* FwdEndPlateShape =
new G4Tubs(
"solid" + name, endPlateRmin, endPlateRmax, 0.5 * fwdEndPlateThick, 0., 360.*CLHEP::deg);
1878 G4LogicalVolume* logical2 =
new G4LogicalVolume(FwdEndPlateShape, medAluminum,
"logical" + name, 0, 0, 0);
1880 z = 48.5 * CLHEP::cm + 0.5 * fwdEndPlateThick;
1881 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 coordinates.
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 indicating 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.