Create detector geometry.
155 G4Transform3D transform_HER = G4Translate3D(0., 0., 0.);
156 transform_HER = transform_HER * G4RotateY3D(crossingAngleHER);
158 G4Transform3D transform_LER = G4Translate3D(0., 0., 0.);
159 transform_LER = transform_LER * G4RotateY3D(crossingAngleLER);
161 map<string, CryostatElement> elements;
167 CryostatElement tubeR;
168 std::string prep =
"TubeR.";
172 std::vector<double> TubeR_Z(TubeR_N);
173 std::vector<double> TubeR_R(TubeR_N);
174 std::vector<double> TubeR_r(TubeR_N);
176 for (
int i = 0; i < TubeR_N; ++i) {
177 ostringstream ossZID;
180 ostringstream ossRID;
183 ostringstream ossrID;
191 tubeR.transform = G4Translate3D(0., 0., 0.);
192 tubeR.geo =
new G4Polycone(
"geo_TubeR_name", 0, 2 * M_PI, TubeR_N, &(TubeR_Z[0]), &(TubeR_r[0]), &(TubeR_R[0]));
194 elements[
"TubeR"] = tubeR;
197 CryostatElement tubeR2;
201 std::vector<double> TubeR2_Z(TubeR2_N);
202 std::vector<double> TubeR2_R(TubeR2_N);
203 std::vector<double> TubeR2_r(TubeR2_N);
205 for (
int i = 0; i < TubeR2_N; ++i) {
206 ostringstream ossZID;
209 ostringstream ossRID;
212 ostringstream ossrID;
220 tubeR2.transform = G4Translate3D(0., 0., 0.);
221 tubeR2.geo =
new G4Polycone(
"geo_TubeR2_name", 0, 2 * M_PI, TubeR2_N, &(TubeR2_Z[0]), &(TubeR2_r[0]), &(TubeR2_R[0]));
223 elements[
"TubeR2"] = tubeR2;
226 CryostatElement tubeL;
230 std::vector<double> TubeL_Z(TubeL_N);
231 std::vector<double> TubeL_R(TubeL_N);
232 std::vector<double> TubeL_r(TubeL_N);
234 for (
int i = 0; i < TubeL_N; ++i) {
235 ostringstream ossZID;
238 ostringstream ossRID;
241 ostringstream ossrID;
249 tubeL.transform = G4Translate3D(0., 0., 0.);
250 tubeL.geo =
new G4Polycone(
"geo_TubeL_name", 0, 2 * M_PI, TubeL_N, &(TubeL_Z[0]), &(TubeL_r[0]), &(TubeL_R[0]));
252 elements[
"TubeL"] = tubeL;
261 CryostatElement A1spc1;
265 std::vector<double> A1spc1_Z(A1spc1_N);
266 std::vector<double> A1spc1_r(A1spc1_N);
267 std::vector<double> A1spc1_R(A1spc1_N);
269 for (
int i = 0; i < A1spc1_N; ++i) {
270 ostringstream ossZID;
273 ostringstream ossRID;
276 ostringstream ossrID;
284 A1spc1.transform = transform_HER;
285 G4Polycone* geo_A1spc1xx =
new G4Polycone(
"geo_A1spc1xx_name", 0, 2 * M_PI, A1spc1_N, &(A1spc1_Z[0]), &(A1spc1_r[0]),
289 CryostatElement A1spc2;
293 std::vector<double> A1spc2_Z(A1spc2_N);
294 std::vector<double> A1spc2_R(A1spc2_N);
295 std::vector<double> A1spc2_r(A1spc2_N);
297 for (
int i = 0; i < A1spc2_N; ++i) {
298 ostringstream ossZID;
301 ostringstream ossRID;
304 ostringstream ossrID;
312 A1spc2.transform = transform_HER;
313 G4Polycone* geo_A1spc2xx =
new G4Polycone(
"geo_A1spc2xx_name", 0, 2 * M_PI, A1spc2_N, &(A1spc2_Z[0]), &(A1spc2_r[0]),
317 CryostatElement B1spc1;
321 std::vector<double> B1spc1_Z(B1spc1_N);
322 std::vector<double> B1spc1_R(B1spc1_N);
323 std::vector<double> B1spc1_r(B1spc1_N);
325 for (
int i = 0; i < B1spc1_N; ++i) {
326 ostringstream ossZID;
329 ostringstream ossRID;
332 ostringstream ossrID;
340 B1spc1.transform = transform_LER;
341 G4Polycone* geo_B1spc1xx =
new G4Polycone(
"geo_B1spc1xx_name", 0, 2 * M_PI, B1spc1_N, &(B1spc1_Z[0]), &(B1spc1_r[0]),
345 CryostatElement B1spc2;
349 std::vector<double> B1spc2_Z(B1spc2_N);
350 std::vector<double> B1spc2_R(B1spc2_N);
351 std::vector<double> B1spc2_r(B1spc2_N);
353 for (
int i = 0; i < B1spc2_N; ++i) {
354 ostringstream ossZID;
357 ostringstream ossRID;
360 ostringstream ossrID;
368 B1spc2.transform = transform_LER;
369 G4Polycone* geo_B1spc2xx =
new G4Polycone(
"geo_B1spc2xx_name", 0, 2 * M_PI, B1spc2_N, &(B1spc2_Z[0]), &(B1spc2_r[0]),
373 B1spc2.geo =
new G4IntersectionSolid(
"geo_B1spc2_name", geo_B1spc2xx, elements[
"TubeR2"].geo, B1spc2.transform.inverse());
376 G4IntersectionSolid* geo_B1spc1x =
new G4IntersectionSolid(
"geo_B1spc1x_name", geo_B1spc1xx, elements[
"TubeR"].geo,
377 B1spc1.transform.inverse());
378 B1spc1.geo =
new G4UnionSolid(
"geo_B1spc1_name", geo_B1spc1x, B1spc2.geo);
380 A1spc2.geo =
new G4IntersectionSolid(
"geo_A1spc2_name", geo_A1spc2xx, elements[
"TubeR2"].geo, A1spc2.transform.inverse());
383 G4IntersectionSolid* geo_A1spc1xy =
new G4IntersectionSolid(
"geo_A1spc1xy_name", geo_A1spc1xx, elements[
"TubeR"].geo,
384 A1spc1.transform.inverse());
385 G4UnionSolid* geo_A1spc1x =
new G4UnionSolid(
"geo_A1spc1x_name", geo_A1spc1xy, A1spc2.geo);
386 A1spc1.geo =
new G4SubtractionSolid(
"geo_A1spc1_name", geo_A1spc1x, B1spc1.geo, A1spc1.transform.inverse()*B1spc1.transform);
390 A1spc1.logi =
new G4LogicalVolume(A1spc1.geo, mat_A1spc1,
"logi_A1spc1_name");
392 A1spc1.logi->SetUserLimits(
new G4UserLimits(stepMax));
397 new G4PVPlacement(A1spc1.transform, A1spc1.logi,
"phys_A1spc1_name", &topVolume,
false, 0);
401 B1spc1.logi =
new G4LogicalVolume(B1spc1.geo, mat_B1spc1,
"logi_B1spc1_name");
403 B1spc1.logi->SetUserLimits(
new G4UserLimits(stepMax));
408 new G4PVPlacement(B1spc1.transform, B1spc1.logi,
"phys_B1spc1_name", &topVolume,
false, 0);
410 elements[
"A1spc1"] = A1spc1;
411 elements[
"A1spc2"] = A1spc2;
412 elements[
"B1spc1"] = B1spc1;
413 elements[
"B1spc2"] = B1spc2;
419 CryostatElement C1wal1;
423 std::vector<double> C1wal1_Z(C1wal1_N);
424 std::vector<double> C1wal1_R(C1wal1_N);
425 std::vector<double> C1wal1_r(C1wal1_N);
427 for (
int i = 0; i < C1wal1_N; ++i) {
428 ostringstream ossZID;
431 ostringstream ossRID;
434 ostringstream ossrID;
442 C1wal1.transform = G4Translate3D(0., 0., 0.);
445 G4Polycone* geo_C1wal1xxx =
new G4Polycone(
"geo_C1wal1xxx_name", 0, 2 * M_PI, C1wal1_N, &(C1wal1_Z[0]), &(C1wal1_r[0]),
447 G4IntersectionSolid* geo_C1wal1xx =
new G4IntersectionSolid(
"geo_C1wal1xx_name", geo_C1wal1xxx, elements[
"TubeR"].geo,
448 elements[
"TubeR"].transform);
449 G4SubtractionSolid* geo_C1wal1x =
new G4SubtractionSolid(
"geo_C1wal1x_name", geo_C1wal1xx, elements[
"A1spc1"].geo,
450 elements[
"A1spc1"].transform);
451 C1wal1.geo =
new G4SubtractionSolid(
"geo_C1wal1_name", geo_C1wal1x, elements[
"B1spc1"].geo, elements[
"B1spc1"].transform);
455 C1wal1.logi =
new G4LogicalVolume(C1wal1.geo, mat_C1wal1,
"logi_C1wal1_name");
460 new G4PVPlacement(0, G4ThreeVector(0, 0, 0), C1wal1.logi,
"phys_C1wal1_name", &topVolume,
false, 0);
462 elements[
"C1wal1"] = C1wal1;
468 CryostatElement D1spc1;
472 std::vector<double> D1spc1_Z(D1spc1_N);
473 std::vector<double> D1spc1_r(D1spc1_N);
474 std::vector<double> D1spc1_R(D1spc1_N);
476 for (
int i = 0; i < D1spc1_N; ++i) {
477 ostringstream ossZID;
480 ostringstream ossRID;
483 ostringstream ossrID;
491 D1spc1.transform = transform_HER;
492 G4Polycone* geo_D1spc1xx =
new G4Polycone(
"geo_D1spc1xx_name", 0, 2 * M_PI, D1spc1_N, &(D1spc1_Z[0]), &(D1spc1_r[0]),
496 CryostatElement E1spc1;
500 std::vector<double> E1spc1_Z(E1spc1_N);
501 std::vector<double> E1spc1_R(E1spc1_N);
502 std::vector<double> E1spc1_r(E1spc1_N);
504 for (
int i = 0; i < E1spc1_N; ++i) {
505 ostringstream ossZID;
508 ostringstream ossRID;
511 ostringstream ossrID;
519 E1spc1.transform = transform_LER;
520 G4Polycone* geo_E1spc1xx =
new G4Polycone(
"geo_E1spc1xx_name", 0, 2 * M_PI, E1spc1_N, &(E1spc1_Z[0]), &(E1spc1_r[0]),
524 G4IntersectionSolid* geo_D1spc1x =
new G4IntersectionSolid(
"geo_D1spc1x_name", geo_D1spc1xx, elements[
"TubeL"].geo,
525 D1spc1.transform.inverse());
526 E1spc1.geo =
new G4IntersectionSolid(
"geo_E1spc1_name", geo_E1spc1xx, elements[
"TubeL"].geo, E1spc1.transform.inverse());
527 D1spc1.geo =
new G4SubtractionSolid(
"geo_D1spc1_name", geo_D1spc1x, E1spc1.geo, D1spc1.transform.inverse()*E1spc1.transform);
531 D1spc1.logi =
new G4LogicalVolume(D1spc1.geo, mat_D1spc1,
"logi_D1spc1_name");
533 D1spc1.logi->SetUserLimits(
new G4UserLimits(stepMax));
538 new G4PVPlacement(D1spc1.transform, D1spc1.logi,
"phys_D1spc1_name", &topVolume,
false, 0);
542 E1spc1.logi =
new G4LogicalVolume(E1spc1.geo, mat_E1spc1,
"logi_E1spc1_name");
544 E1spc1.logi->SetUserLimits(
new G4UserLimits(stepMax));
549 new G4PVPlacement(E1spc1.transform, E1spc1.logi,
"phys_E1spc1_name", &topVolume,
false, 0);
551 elements[
"E1spc1"] = E1spc1;
552 elements[
"D1spc1"] = D1spc1;
559 CryostatElement F1wal1;
563 std::vector<double> F1wal1_Z(F1wal1_N);
564 std::vector<double> F1wal1_R(F1wal1_N);
565 std::vector<double> F1wal1_r(F1wal1_N);
567 for (
int i = 0; i < F1wal1_N; ++i) {
568 ostringstream ossZID;
571 ostringstream ossRID;
574 ostringstream ossrID;
582 F1wal1.transform = G4Translate3D(0., 0., 0.);
585 G4Polycone* geo_F1wal1xxx =
new G4Polycone(
"geo_F1wal1xxx_name", 0, 2 * M_PI, F1wal1_N, &(F1wal1_Z[0]), &(F1wal1_r[0]),
587 G4IntersectionSolid* geo_F1wal1xx =
new G4IntersectionSolid(
"geo_F1wal1xx_name", geo_F1wal1xxx, elements[
"TubeL"].geo,
588 elements[
"TubeL"].transform);
589 G4SubtractionSolid* geo_F1wal1x =
new G4SubtractionSolid(
"geo_F1wal1x_name", geo_F1wal1xx, elements[
"D1spc1"].geo,
590 elements[
"D1spc1"].transform);
591 F1wal1.geo =
new G4SubtractionSolid(
"geo_F1wal1_name", geo_F1wal1x, elements[
"E1spc1"].geo, elements[
"E1spc1"].transform);
595 F1wal1.logi =
new G4LogicalVolume(F1wal1.geo, mat_F1wal1,
"logi_F1wal1_name");
600 new G4PVPlacement(F1wal1.transform, F1wal1.logi,
"phys_F1wal1_name", &topVolume,
false, 0);
602 elements[
"F1wal1"] = F1wal1;
607 std::vector<std::string> straightSections;
609 for (
const auto& name : straightSections) {
612 CryostatElement polycone;
616 std::vector<double> Z(N);
617 std::vector<double> R(N);
618 std::vector<double> r(N);
620 for (
int i = 0; i < N; ++i) {
621 ostringstream ossZID;
624 ostringstream ossRID;
627 ostringstream ossrID;
635 polycone.transform = G4Translate3D(0.0, 0.0, 0.0);
642 string geo_polyconexx_name =
"geo_" + name +
"xx_name";
643 string geo_polyconex_name =
"geo_" + name +
"x_name";
644 string geo_polycone_name =
"geo_" + name +
"_name";
646 G4VSolid* geo_polyconexx, *geo_polycone;
649 geo_polyconexx =
new G4Polycone(geo_polyconexx_name, 0.0, 2 * M_PI, N, &(Z[0]), &(r[0]), &(R[0]));
650 G4VSolid* geo_polyconex =
new G4SubtractionSolid(geo_polyconex_name, geo_polyconexx, elements[subtract].geo,
651 elements[motherVolume].transform.inverse()*polycone.transform.inverse()*elements[subtract].transform);
652 geo_polycone =
new G4IntersectionSolid(geo_polycone_name, geo_polyconex, elements[
intersect].geo,
653 elements[motherVolume].transform.inverse()*polycone.transform.inverse()*elements[
intersect].transform);
654 }
else if (subtract !=
"") {
655 geo_polyconexx =
new G4Polycone(geo_polyconexx_name, 0.0, 2 * M_PI, N, &(Z[0]), &(r[0]), &(R[0]));
656 geo_polycone =
new G4SubtractionSolid(geo_polycone_name, geo_polyconexx, elements[subtract].geo,
657 elements[motherVolume].transform.inverse()*polycone.transform.inverse()*elements[subtract].transform);
659 geo_polyconexx =
new G4Polycone(geo_polyconexx_name, 0.0, 2 * M_PI, N, &(Z[0]), &(r[0]), &(R[0]));
660 geo_polycone =
new G4IntersectionSolid(geo_polycone_name, geo_polyconexx, elements[
intersect].geo,
661 elements[motherVolume].transform.inverse()*polycone.transform.inverse()*elements[
intersect].transform);
663 geo_polycone =
new G4Polycone(geo_polycone_name, 0.0, 2 * M_PI, N, &(Z[0]), &(r[0]), &(R[0]));
665 polycone.geo = geo_polycone;
670 string logi_polycone_name =
"logi_" + name +
"_name";
671 polycone.logi =
new G4LogicalVolume(polycone.geo, mat_polycone, logi_polycone_name);
672 setColor(*polycone.logi,
"#CC0000");
676 string phys_polycone_name =
"phys_" + name +
"_name";
677 new G4PVPlacement(polycone.transform, polycone.logi, phys_polycone_name, elements[motherVolume].logi,
false, 0);
680 polycone.transform = polycone.transform * elements[motherVolume].transform;
682 elements[name] = polycone;
686 G4Tubs* geo_rvcR =
new G4Tubs(
"geo_rvcR", 60, 60 + 60, (620 - 560) / 2., 0, 2 * M_PI);
687 G4LogicalVolume* logi_rvcR =
new G4LogicalVolume(geo_rvcR,
Materials::get(
"SUS316L"),
"logi_rvcR_name");
688 new G4PVPlacement(0, G4ThreeVector(0, 0, (620 + 560) / 2.), logi_rvcR,
"phys_rvcR_name", &topVolume,
false, 0);
690 G4Tubs* geo_rvcL =
new G4Tubs(
"geo_rvcL", 60, 60 + 60, (-560 - (-620)) / 2., 0, 2 * M_PI);
691 G4LogicalVolume* logi_rvcL =
new G4LogicalVolume(geo_rvcL,
Materials::get(
"SUS316L"),
"logi_rvcL_name");
692 new G4PVPlacement(0, G4ThreeVector(0, 0, (-620 - 560) / 2.), logi_rvcL,
"phys_rvcL_name", &topVolume,
false, 0);
696 G4EllipticalTube* geo_elp_QC1LEx =
new G4EllipticalTube(
"geo_elp_QC1LEx", 10.5, 13.5, (-675 - (-1225)) / 2.);
697 G4IntersectionSolid* geo_elp_QC1LE =
new G4IntersectionSolid(
"geo_elp_QC1LE", elements[
"D2wal1"].geo, geo_elp_QC1LEx,
698 G4Translate3D(0, 0, (-675 - 1225) / 2.));
699 G4LogicalVolume* logi_elp_QC1LE =
new G4LogicalVolume(geo_elp_QC1LE,
Materials::get(
"Vacuum"),
"logi_elp_QC1LE_name");
700 new G4PVPlacement(0, G4ThreeVector(0, 0, 0), logi_elp_QC1LE,
"phys_elp_QC1LE_name", elements[
"D2wal1"].logi,
false, 0);
702 G4EllipticalTube* geo_elp_QC1LPx =
new G4EllipticalTube(
"geo_elp_QC1LPx", 10.5, 13.5, (-675 - (-1225)) / 2.);
703 G4IntersectionSolid* geo_elp_QC1LP =
new G4IntersectionSolid(
"geo_elp_QC1LP", elements[
"E2wal1"].geo, geo_elp_QC1LPx,
704 G4Translate3D(0, 0, (-675 - 1225) / 2.));
705 G4LogicalVolume* logi_elp_QC1LP =
new G4LogicalVolume(geo_elp_QC1LP,
Materials::get(
"Vacuum"),
"logi_elp_QC1LP_name");
706 new G4PVPlacement(0, G4ThreeVector(0, 0, 0), logi_elp_QC1LP,
"phys_elp_QC1LP_name", elements[
"E2wal1"].logi,
false, 0);
708 G4EllipticalTube* geo_elp_QC1REx =
new G4EllipticalTube(
"geo_elp_QC1REx", 10.5, 13.5, (1225 - 675) / 2.);
709 G4IntersectionSolid* geo_elp_QC1RE =
new G4IntersectionSolid(
"geo_elp_QC1RE", elements[
"A2wal1"].geo, geo_elp_QC1REx,
710 G4Translate3D(0, 0, (1225 + 675) / 2.));
711 G4LogicalVolume* logi_elp_QC1RE =
new G4LogicalVolume(geo_elp_QC1RE,
Materials::get(
"Vacuum"),
"logi_elp_QC1RE_name");
712 new G4PVPlacement(0, G4ThreeVector(0, 0, 0), logi_elp_QC1RE,
"phys_elp_QC1RE_name", elements[
"A2wal1"].logi,
false, 0);
714 G4EllipticalTube* geo_elp_QC1RPx =
new G4EllipticalTube(
"geo_elp_QC1RPx", 10.5, 13.5, (1225 - 675) / 2.);
715 G4IntersectionSolid* geo_elp_QC1RP =
new G4IntersectionSolid(
"geo_elp_QC1RP", elements[
"B2wal1"].geo, geo_elp_QC1RPx,
716 G4Translate3D(0, 0, (1225 + 675) / 2.));
717 G4LogicalVolume* logi_elp_QC1RP =
new G4LogicalVolume(geo_elp_QC1RP,
Materials::get(
"Vacuum"),
"logi_elp_QC1RP_name");
718 new G4PVPlacement(0, G4ThreeVector(0, 0, 0), logi_elp_QC1RP,
"phys_elp_QC1RP_name", elements[
"B2wal1"].logi,
false, 0);
double getParameter(const std::string &name) const
Get parameter value.
const std::string & getParameterStr(const std::string &name) const
Get string parameter.
static const double mm
[millimeters]
static const double cm
Standard units with the value = 1.
static G4Material * get(const std::string &name)
Find given material.
int intersect(const TRGCDCLpar &lp1, const TRGCDCLpar &lp2, CLHEP::HepVector &v1, CLHEP::HepVector &v2)
intersection
void setVisibility(G4LogicalVolume &volume, bool visible)
Helper function to quickly set the visibility of a given volume.
void setColor(G4LogicalVolume &volume, const std::string &color)
Set the color of a logical volume.