10#include <klm/eklm/geometry/GeoEKLMCreator.h>
13#include <klm/eklm/geometry/G4TriangularPrism.h>
14#include <klm/simulation/SensitiveDetector.h>
17#include <geometry/CreatorFactory.h>
18#include <geometry/Materials.h>
19#include <geometry/utilities.h>
23#include <G4Polyhedra.hh>
24#include <G4PVPlacement.hh>
27#include <G4UnionSolid.hh>
30#include <CLHEP/Units/SystemOfUnits.h>
38static const char MemErr[] =
"Memory allocation error.";
78 static_cast<G4VSolid**
>(malloc(
m_GeoDat->getNPlanes() *
sizeof(G4VSolid*)));
82 static_cast<G4VSolid**
>(malloc(
m_GeoDat->getNStrips() *
sizeof(G4VSolid*)));
83 if (
m_Solids.plasticSheetElement ==
nullptr)
86 static_cast<G4VSolid**
>(malloc(
m_GeoDat->getNSegments() *
sizeof(G4VSolid*)));
89 m_LogVol.psheet =
static_cast<G4LogicalVolume**
>(malloc(
m_GeoDat->getNSegments() *
sizeof(G4LogicalVolume*)));
93 static_cast<G4LogicalVolume**
>(malloc(
m_GeoDat->getNSegments() *
94 sizeof(G4LogicalVolume*)));
98 static_cast<G4VSolid**
>(malloc(
m_GeoDat->getNSegments() *
sizeof(G4VSolid*)));
99 if (
m_Solids.stripSegment ==
nullptr)
102 static_cast<G4LogicalVolume**
>(malloc(
m_GeoDat->getNSegments() *
103 sizeof(G4LogicalVolume*)));
104 if (
m_LogVol.stripSegment ==
nullptr)
106 nDiff =
m_GeoDat->getNStripsDifferentLength();
107 m_Solids.strip =
static_cast<G4VSolid**
>(malloc(nDiff *
sizeof(G4VSolid*)));
110 m_LogVol.strip =
static_cast<G4LogicalVolume**
>(malloc(nDiff *
sizeof(G4LogicalVolume*)));
113 m_Solids.groove =
static_cast<G4VSolid**
>(malloc(nDiff *
sizeof(G4VSolid*)));
116 m_LogVol.groove =
static_cast<G4LogicalVolume**
>(malloc(nDiff *
sizeof(G4LogicalVolume*)));
119 m_LogVol.scint =
static_cast<G4LogicalVolume**
>(malloc(nDiff *
sizeof(G4LogicalVolume*)));
123 static_cast<G4LogicalVolume***
>(malloc(
m_GeoDat->getNPlanes() *
124 sizeof(G4LogicalVolume**)));
127 for (i = 0; i <
m_GeoDat->getNPlanes(); i++) {
129 static_cast<G4LogicalVolume**
>(malloc((
m_GeoDat->getNSegments() + 1) *
130 sizeof(G4LogicalVolume*)));
131 if (
m_LogVol.segmentsup[i] ==
nullptr)
134 for (i = 0; i <
m_GeoDat->getNSegments(); i++)
143 }
catch (std::bad_alloc& ba) {
163 for (i = 0; i <
m_GeoDat->getNPlanes(); i++)
192 m_GeoDat->getEndcapStructureGeometry();
195 const double z[2] = { -sectionPos->
getLength() / 2,
198 const double rMin[2] = {0, 0};
200 G4Polyhedra* op =
nullptr;
201 G4Tubs* tb =
nullptr;
203 op =
new G4Polyhedra(
"Section_Octagonal_Prism",
204 sectionStructureGeometry->
getPhi(),
208 }
catch (std::bad_alloc& ba) {
213 tb =
new G4Tubs(
"Section_Tube", 0, sectionPos->
getInnerR(),
214 sectionPos->
getLength() / 2.0 + 1.0 * CLHEP::mm,
215 0.0, 360.0 * CLHEP::deg);
216 }
catch (std::bad_alloc& ba) {
220 m_Solids.section =
new G4SubtractionSolid(
"Section", op, tb);
221 }
catch (std::bad_alloc& ba) {
229 G4LogicalVolume* logicLayer =
nullptr;
232 }
catch (std::bad_alloc& ba) {
245 layerPos->
getLength() / 2.0, 0.0, 360. * CLHEP::deg);
246 }
catch (std::bad_alloc& ba) {
254 G4LogicalVolume* logicSector =
nullptr;
257 }
catch (std::bad_alloc& ba) {
271 0.5 * sectorPos->
getLength(), 0.0, 90. * CLHEP::deg);
272 }
catch (std::bad_alloc& ba) {
280 HepGeom::Transform3D t1;
281 HepGeom::Transform3D t2;
282 G4Tubs* solidCoverTube =
nullptr;
283 G4Box* solidCoverBox =
nullptr;
284 G4Box* box =
nullptr;
285 G4IntersectionSolid* is =
nullptr;
286 G4SubtractionSolid* solidCover =
nullptr;
290 m_GeoDat->getSectorSupportPosition();
292 m_GeoDat->getSectorSupportGeometry();
296 solidCoverTube =
new G4Tubs(
"Cover_Tube", sectorSupportPos->
getInnerR(),
297 sectorSupportPos->
getOuterR(), 0.5 * lz, 0.0,
299 }
catch (std::bad_alloc& ba) {
303 solidCoverBox =
new G4Box(
"Cover_Box", 0.5 * sectorSupportPos->
getOuterR(),
304 0.5 * sectorSupportPos->
getOuterR(), 0.5 * lz);
305 }
catch (std::bad_alloc& ba) {
309 box =
new G4Box(
"Cover_SubtractionBox", 0.5 * sectorSupportPos->
getOuterR(),
310 0.5 * sectorSupportPos->
getOuterR(), lz);
311 }
catch (std::bad_alloc& ba) {
314 t1 = HepGeom::Translate3D(
318 t2 = HepGeom::Translate3D(
319 sectorSupportPos->
getX() +
320 0.5 * sectorSupportPos->
getOuterR() * cos(ang) -
321 0.5 * sectorSupportPos->
getOuterR() * sin(ang),
324 0.5 * sectorSupportPos->
getOuterR() * cos(ang) +
325 0.5 * sectorSupportPos->
getOuterR() * sin(ang),
326 0.) * HepGeom::RotateZ3D(ang);
328 is =
new G4IntersectionSolid(
"Cover_Intersection",
329 solidCoverTube, solidCoverBox, t1);
330 }
catch (std::bad_alloc& ba) {
334 solidCover =
new G4SubtractionSolid(
"Cover", is, box, t2);
335 }
catch (std::bad_alloc& ba) {
340 new G4LogicalVolume(solidCover,
m_Materials.duralumin,
"Cover");
341 }
catch (std::bad_alloc& ba) {
351 G4Box* res =
nullptr;
353 m_GeoDat->getSectorSupportPosition();
355 m_GeoDat->getSectorSupportGeometry();
357 sectorSupportPos->
getY() * sectorSupportPos->
getY());
358 t = HepGeom::Translate3D(0.5 * (x + sectorSupportGeometry->
getCorner3().x()),
359 sectorSupportPos->
getY() +
362 res =
new G4Box(
"SectorSupport_BoxX",
363 0.5 * (x - sectorSupportGeometry->
getCorner3().x()),
366 }
catch (std::bad_alloc& ba) {
374 G4Box* res =
nullptr;
376 m_GeoDat->getSectorSupportPosition();
378 m_GeoDat->getSectorSupportGeometry();
379 t = HepGeom::Translate3D(sectorSupportPos->
getX() +
381 0.5 * (sectorSupportGeometry->
getCorner4().y() +
383 0.) * HepGeom::RotateZ3D(90. * CLHEP::deg);
385 res =
new G4Box(
"SectorSupport_BoxY",
390 }
catch (std::bad_alloc& ba) {
400 G4Box* res =
nullptr;
402 m_GeoDat->getSectorSupportPosition();
404 m_GeoDat->getSectorSupportGeometry();
405 t = HepGeom::Translate3D(
414 0.) * HepGeom::RotateZ3D(sectorSupportGeometry->
getCornerAngle());
420 res =
new G4Box(
"SectorSupport_BoxTop", 0.5 *
sqrt(dx * dx + dy * dy),
423 }
catch (std::bad_alloc& ba) {
433 G4Tubs* res =
nullptr;
435 m_GeoDat->getSectorSupportPosition();
437 m_GeoDat->getSectorSupportGeometry();
438 ang1 = atan2(sectorSupportGeometry->
getCorner3().y(),
440 ang2 = atan2(sectorSupportGeometry->
getCorner4().y(),
443 res =
new G4Tubs(
"SectorSupport_InnerTube", sectorSupportPos->
getInnerR(),
447 ang1 * CLHEP::rad, (ang2 - ang1) * CLHEP::rad);
448 }
catch (std::bad_alloc& ba) {
460 G4Tubs* res =
nullptr;
462 m_GeoDat->getSectorSupportPosition();
464 m_GeoDat->getSectorSupportGeometry();
466 x =
sqrt(r * r - sectorSupportPos->
getY() * sectorSupportPos->
getY());
467 ang1 = atan2(sectorSupportPos->
getY(), x);
468 ang2 = atan2(sectorSupportGeometry->
getCorner1B().y(),
471 res =
new G4Tubs(
"SectorSupport_OuterTube", r,
474 ang1 * CLHEP::rad, (ang2 - ang1) * CLHEP::rad);
475 }
catch (std::bad_alloc& ba) {
485 G4Tubs* solidCorner1Tube =
nullptr;
486 G4Box* solidCorner1Box1 =
nullptr;
487 G4Box* solidCorner1Box2 =
nullptr;
488 G4IntersectionSolid* is1 =
nullptr;
489 G4IntersectionSolid* solidCorner1 =
nullptr;
490 HepGeom::Transform3D t1;
491 HepGeom::Transform3D t2;
493 m_GeoDat->getSectorSupportPosition();
495 m_GeoDat->getSectorSupportGeometry();
500 solidCorner1Tube =
new G4Tubs(
501 "SectorSupport_Corner1_Tube", 0.,
504 0., 90. * CLHEP::deg);
505 }
catch (std::bad_alloc& ba) {
509 solidCorner1Box1 =
new G4Box(
510 "SectorSupport_Corner1_Box1", 0.5 * lx,
513 }
catch (std::bad_alloc& ba) {
518 new G4Box(
"SectorSupport_Corner1_Box2",
524 }
catch (std::bad_alloc& ba) {
527 x = sectorSupportPos->
getX() + 0.5 * (sectorSupportGeometry->
getCornerX() +
530 t1 = HepGeom::Translate3D(x, 0.5 * sectorSupportPos->
getOuterR(), 0.);
531 t2 = HepGeom::Translate3D(
538 is1 =
new G4IntersectionSolid(
"SectorSupport_Corner1_Intersection1",
539 solidCorner1Tube, solidCorner1Box1, t1);
540 }
catch (std::bad_alloc& ba) {
544 solidCorner1 =
new G4IntersectionSolid(
"SectorSupport_Corner1", is1,
545 solidCorner1Box2, t2);
546 }
catch (std::bad_alloc& ba) {
551 new G4LogicalVolume(solidCorner1,
m_Materials.duralumin,
"Corner1");
552 }
catch (std::bad_alloc& ba) {
562 G4SubtractionSolid* solidCorner2 =
nullptr;
563 HepGeom::Transform3D t1;
565 m_GeoDat->getSectorSupportGeometry();
574 }
catch (std::bad_alloc& ba) {
577 t1 = HepGeom::Translate3D(-sectorSupportGeometry->
getCorner2Inner().x(),
580 solidCorner2 =
new G4SubtractionSolid(
"SectorSupport_Corner2",
583 }
catch (std::bad_alloc& ba) {
586 delete solidCorner2Prism;
589 new G4LogicalVolume(solidCorner2,
m_Materials.duralumin,
"Corner2");
590 }
catch (std::bad_alloc& ba) {
600 G4SubtractionSolid* solidCorner3 =
nullptr;
601 HepGeom::Transform3D t1;
603 m_GeoDat->getSectorSupportGeometry();
611 }
catch (std::bad_alloc& ba) {
614 t1 = HepGeom::Translate3D(-sectorSupportGeometry->
getCorner3Prism().x(),
617 solidCorner3 =
new G4SubtractionSolid(
"SectorSupport_Corner3",
620 }
catch (std::bad_alloc& ba) {
623 delete solidCorner3Prism;
626 new G4LogicalVolume(solidCorner3,
m_Materials.duralumin,
"Corner3");
627 }
catch (std::bad_alloc& ba) {
637 G4SubtractionSolid* solidCorner4 =
nullptr;
638 HepGeom::Transform3D t1;
640 m_GeoDat->getSectorSupportGeometry();
648 }
catch (std::bad_alloc& ba) {
651 t1 = HepGeom::Translate3D(-sectorSupportGeometry->
getCorner4Prism().x(),
654 solidCorner4 =
new G4SubtractionSolid(
"SectorSupport_Corner4",
657 }
catch (std::bad_alloc& ba) {
660 delete solidCorner4Prism;
663 new G4LogicalVolume(solidCorner4,
m_Materials.duralumin,
"Corner4");
664 }
catch (std::bad_alloc& ba) {
676 G4Tubs* solidLimitationTube =
nullptr;
677 G4UnionSolid* us1 =
nullptr;
678 G4UnionSolid* us2 =
nullptr;
679 G4UnionSolid* us3 =
nullptr;
680 G4UnionSolid* us4 =
nullptr;
681 G4IntersectionSolid* solidSectorSupport =
nullptr;
682 HepGeom::Transform3D tbx;
683 HepGeom::Transform3D tby;
684 HepGeom::Transform3D tbt;
686 m_GeoDat->getSectorSupportPosition();
693 solidLimitationTube =
new G4Tubs(
"SectorSupport_LimitationTube",
697 }
catch (std::bad_alloc& ba) {
701 us1 =
new G4UnionSolid(
"SectorSupport_Union1",
702 m_Solids.sectorsup.itube, solidBoxY, tby);
703 }
catch (std::bad_alloc& ba) {
707 us2 =
new G4UnionSolid(
"SectorSupport_Union2",
708 us1, solidBoxX, tbx);
709 }
catch (std::bad_alloc& ba) {
713 us3 =
new G4UnionSolid(
"SectorSupport_Union3", us2,
715 HepGeom::Translate3D(0., 0., 0.));
716 }
catch (std::bad_alloc& ba) {
720 us4 =
new G4UnionSolid(
"SectorSupport_Union4",
721 us3, solidBoxTop, tbt);
722 }
catch (std::bad_alloc& ba) {
727 new G4IntersectionSolid(
"SectorSupport", us4, solidLimitationTube,
728 HepGeom::Translate3D(0., 0., 0.));
729 }
catch (std::bad_alloc& ba) {
734 new G4LogicalVolume(solidSectorSupport,
m_Materials.duralumin,
"Support");
735 }
catch (std::bad_alloc& ba) {
746 m_GeoDat->getSectorSupportPosition();
749 new G4Box(
"SubractionBox", 0.5 * sectorSupportPos->
getOuterR(),
751 }
catch (std::bad_alloc& ba) {
757cutSolidCorner(
const char* name, G4VSolid* solid, G4Box* subtractionBox,
758 const HepGeom::Transform3D& transf,
bool largerAngles,
759 double x1,
double y1,
double x2,
double y2)
762 ang = atan2(y2 - y1, x2 - x1);
763 return cutSolidCorner(name, solid, subtractionBox, transf, largerAngles,
768cutSolidCorner(
const char* name, G4VSolid* solid, G4Box* subtractionBox,
769 const HepGeom::Transform3D& transf,
bool largerAngles,
770 double x,
double y,
double ang)
773 HepGeom::Transform3D t;
774 G4SubtractionSolid* ss =
nullptr;
775 lx = subtractionBox->GetXHalfLength();
776 ly = subtractionBox->GetYHalfLength();
778 t = HepGeom::Translate3D(x + lx * cos(ang) - ly * sin(ang),
779 y + lx * sin(ang) + ly * cos(ang), 0) *
780 HepGeom::RotateZ3D(ang);
782 t = HepGeom::Translate3D(x + lx * cos(ang) + ly * sin(ang),
783 y + lx * sin(ang) - ly * cos(ang), 0) *
784 HepGeom::RotateZ3D(ang);
786 ss =
new G4SubtractionSolid(name, solid, subtractionBox, transf * t);
787 }
catch (std::bad_alloc& ba) {
797 HepGeom::Transform3D t;
798 HepGeom::Transform3D t1;
800 G4Tubs* tb =
nullptr;
801 G4IntersectionSolid* is =
nullptr;
802 G4SubtractionSolid* ss1, *ss2, *ss3, *ss4;
804 m_GeoDat->getSectorSupportPosition();
806 m_GeoDat->getSectorSupportGeometry();
809 snprintf(name, 128,
"Plane_%d_Tube", n + 1);
812 0.5 * planePos->
getLength(), 0.0, 90.0 * CLHEP::deg);
813 }
catch (std::bad_alloc& ba) {
816 snprintf(name, 128,
"Plane_%d_Box", n + 1);
820 t1 = HepGeom::Translate3D(
m_Solids.subtractionBox->GetXHalfLength() + box_x,
821 m_Solids.subtractionBox->GetXHalfLength() + box_y,
825 t = HepGeom::Rotate3D(180. * CLHEP::deg,
826 HepGeom::Vector3D<double>(1., 1., 0.));
829 t = HepGeom::Translate3D(0, 0, 0);
831 snprintf(name, 128,
"Plane_%d_Intersection", n + 1);
833 is =
new G4IntersectionSolid(name, tb,
m_Solids.subtractionBox, t1);
834 }
catch (std::bad_alloc& ba) {
837 snprintf(name, 128,
"Plane_%d_Subtraction_1", n + 1);
842 snprintf(name, 128,
"Plane_%d_Subtraction_2", n + 1);
844 name, ss1,
m_Solids.subtractionBox, t,
false,
851 snprintf(name, 128,
"Plane_%d_Subtraction_3", n + 1);
853 name, ss2,
m_Solids.subtractionBox, t,
false,
860 snprintf(name, 128,
"Plane_%d_Subtraction_4", n + 1);
862 name, ss3,
m_Solids.subtractionBox, t,
true,
869 snprintf(name, 128,
"Plane_%d", n + 1);
876 HepGeom::Transform3D t1, t2;
877 G4Box* topBox =
nullptr;
878 G4Box* midBox =
nullptr;
879 G4Box* botBox =
nullptr;
880 G4UnionSolid* us =
nullptr;
881 G4UnionSolid* solidSegmentSupport =
nullptr;
882 std::string segmentSupportName =
883 "SegmentSupport_" + std::to_string(iSegmentSupport) +
884 "_Plane_" + std::to_string(iPlane);
886 m_GeoDat->getSegmentSupportPosition(iPlane, iSegmentSupport);
888 m_GeoDat->getSegmentSupportGeometry();
890 topBox =
new G4Box(
"BoxTop_" + segmentSupportName,
896 }
catch (std::bad_alloc& ba) {
900 midBox =
new G4Box(
"BoxMiddle_" + segmentSupportName,
906 }
catch (std::bad_alloc& ba) {
910 botBox =
new G4Box(
"BoxBottom_" + segmentSupportName,
914 }
catch (std::bad_alloc& ba) {
917 t1 = HepGeom::Translate3D(
920 t2 = HepGeom::Translate3D(
926 us =
new G4UnionSolid(
"Union1_" + segmentSupportName, midBox, topBox, t1);
927 }
catch (std::bad_alloc& ba) {
931 solidSegmentSupport =
new G4UnionSolid(segmentSupportName, us, botBox, t2);
932 }
catch (std::bad_alloc& ba) {
936 m_LogVol.segmentsup[iPlane - 1][iSegmentSupport - 1] =
937 new G4LogicalVolume(solidSegmentSupport,
m_Materials.duralumin,
939 }
catch (std::bad_alloc& ba) {
949unifySolids(G4VSolid** solids, HepGeom::Transform3D* transf,
950 int nSolids,
const std::string& name)
954 G4VSolid** solidArray;
955 HepGeom::Transform3D* inverseTransf;
956 HepGeom::Transform3D t;
959 int n, nUnions, i, i1, i2, k, k1, k2, l, dl;
961 B2FATAL(
"Number of solids to be unified must be greater than 1.");
963 inverseTransf =
new HepGeom::Transform3D[nSolids];
964 }
catch (std::bad_alloc& ba) {
967 for (i = 0; i < nSolids; i++)
968 inverseTransf[i] = transf[i].inverse();
976 nUnions = nUnions + n;
978 u =
static_cast<G4UnionSolid**
>(malloc(
sizeof(G4UnionSolid*) * nUnions));
996 for (i = i1; i < i2; i++) {
999 t = inverseTransf[l] * transf[l + dl];
1001 snprintf(str, 128,
"_Union_%d", i + 1);
1002 u[i] =
new G4UnionSolid(name + str, solidArray[k],
1003 solidArray[k + 1], t);
1004 }
catch (std::bad_alloc& ba) {
1009 u[i] =
static_cast<G4UnionSolid*
>(solids[k]);
1014 solidArray =
reinterpret_cast<G4VSolid**
>(u);
1019 d =
new G4DisplacedSolid(name +
"_Displaced", u[nUnions - 1], transf[0]);
1021 delete[] inverseTransf;
1031 G4VSolid** elements;
1032 HepGeom::Transform3D* t;
1034 m_GeoDat->getPlasticSheetGeometry();
1038 elements =
new G4VSolid*[nStrip];
1039 t =
new HepGeom::Transform3D[nStrip];
1041 for (i = 0; i < nStrip; i++) {
1042 m = nStrip * iSegment + i;
1043 m_GeoDat->getSheetTransform(&(t[i]), m);
1046 for (i = 0; i < nStrip; i++) {
1047 snprintf(name, 128,
"PlasticSheet_%d_Element_%d", iSegment + 1, i + 1);
1049 if (i == 0 || i == nStrip - 1)
1050 ly = ly - plasticSheetGeometry->
getDeltaL();
1051 m = nStrip * iSegment + i;
1056 new G4Box(name, 0.5 * stripPos->
getLength(), 0.5 * ly,
1057 0.5 * plasticSheetGeometry->
getWidth());
1058 }
catch (std::bad_alloc& ba) {
1061 elements[i] =
m_Solids.plasticSheetElement[m];
1064 snprintf(name, 128,
"PlasticSheet_%d", iSegment + 1);
1068 new G4LogicalVolume(
m_Solids.psheet[iSegment],
1070 }
catch (std::bad_alloc& ba) {
1085 HepGeom::Transform3D* t;
1087 strips =
new G4VSolid*[nStrip];
1088 t =
new HepGeom::Transform3D[nStrip];
1089 for (i = 0; i < nStrip; i++) {
1090 m = nStrip * iSegment + i;
1091 m_GeoDat->getStripTransform(&(t[i]), m);
1094 snprintf(name, 128,
"StripSegment_%d", iSegment + 1);
1100 }
catch (std::bad_alloc& ba) {
1113 G4UnionSolid* u1, *u2;
1114 HepGeom::Transform3D t;
1116 m_GeoDat->getPlasticSheetGeometry();
1120 snprintf(name, 128,
"Segment_%d_Union_1", iSegment + 1);
1121 t = HepGeom::Translate3D(0, 0, -z);
1123 u1 =
new G4UnionSolid(name,
m_Solids.stripSegment[iSegment],
1125 }
catch (std::bad_alloc& ba) {
1128 snprintf(name, 128,
"Segment_%d", iSegment + 1);
1129 t = HepGeom::Translate3D(0, 0, z);
1131 u2 =
new G4UnionSolid(name, u1,
m_Solids.psheet[iSegment], t);
1132 }
catch (std::bad_alloc& ba) {
1138 }
catch (std::bad_alloc& ba) {
1152 iPos =
m_GeoDat->getStripPositionIndex(iStrip);
1153 stripPos =
m_GeoDat->getStripPosition(iPos + 1);
1154 snprintf(name, 128,
"Strip_%d", iStrip + 1);
1159 }
catch (std::bad_alloc& ba) {
1166 }
catch (std::bad_alloc& ba) {
1180 iPos =
m_GeoDat->getStripPositionIndex(iStrip);
1181 stripPos =
m_GeoDat->getStripPosition(iPos + 1);
1182 snprintf(name, 128,
"Groove_%d", iStrip + 1);
1187 }
catch (std::bad_alloc& ba) {
1193 }
catch (std::bad_alloc& ba) {
1207 HepGeom::Transform3D t;
1209 G4SubtractionSolid* scintillatorSolid;
1210 iPos =
m_GeoDat->getStripPositionIndex(iStrip);
1211 stripPos =
m_GeoDat->getStripPosition(iPos + 1);
1212 snprintf(name, 128,
"StripSensitive_%d_Box", iStrip + 1);
1221 }
catch (std::bad_alloc& ba) {
1224 snprintf(name, 128,
"StripSensitive_%d", iStrip + 1);
1225 t = HepGeom::Translate3D(0., 0., 0.5 * (stripGeometry->
getThickness() -
1229 new G4SubtractionSolid(name, b,
m_Solids.groove[iStrip], t);
1230 }
catch (std::bad_alloc& ba) {
1235 new G4LogicalVolume(scintillatorSolid,
m_Materials.polystyrene,
1237 }
catch (std::bad_alloc& ba) {
1246 G4Box* box =
nullptr;
1247 G4SubtractionSolid* ss1, *ss2, *ss3, *solidDetailA;
1253 HepGeom::Transform3D t = HepGeom::Translate3D(0, 0, 0);
1257 box =
new G4Box(
"ShieldDetailA_Box", lx, ly,
1259 }
catch (std::bad_alloc& ba) {
1288 new G4LogicalVolume(solidDetailA,
m_Materials.polyethylene,
1290 }
catch (std::bad_alloc& ba) {
1299 G4Box* box =
nullptr;
1300 G4SubtractionSolid* ss1, *solidDetailB;
1306 HepGeom::Transform3D t = HepGeom::Translate3D(0, 0, 0);
1310 box =
new G4Box(
"ShieldDetailB_Box", lx, ly,
1312 }
catch (std::bad_alloc& ba) {
1329 new G4LogicalVolume(solidDetailB,
m_Materials.polyethylene,
1331 }
catch (std::bad_alloc& ba) {
1340 G4Box* box =
nullptr;
1341 G4SubtractionSolid* ss1, *ss2, *ss3, *solidDetailC;
1347 HepGeom::Transform3D t = HepGeom::Translate3D(0, 0, 0);
1351 box =
new G4Box(
"ShieldDetailC_Box", lx, ly,
1353 }
catch (std::bad_alloc& ba) {
1382 new G4LogicalVolume(solidDetailC,
m_Materials.polyethylene,
1384 }
catch (std::bad_alloc& ba) {
1404 }
catch (std::bad_alloc& ba) {
1409 new G4LogicalVolume(solidDetailDPrism->
getSolid(),
1411 }
catch (std::bad_alloc& ba) {
1416 delete solidDetailDPrism;
1422 HepGeom::Transform3D t;
1439 for (i = 0; i <
m_GeoDat->getNPlanes(); i++) {
1442 for (j = 1; j <=
m_GeoDat->getNSegments() + 1; j++)
1446 n =
m_GeoDat->getNStripsDifferentLength();
1447 for (i = 0; i < n; i++) {
1453 for (i = 0; i <
m_GeoDat->getNSegments(); i++)
1456 for (i = 0; i <
m_GeoDat->getNSegments(); i++)
1459 for (i = 0; i <
m_GeoDat->getNSegments(); i++)
1473 G4LogicalVolume* logicSection =
nullptr;
1474 const HepGeom::Transform3D* t;
1475 std::string sectionName =
"Section_" + std::to_string(
m_CurVol.section);
1479 }
catch (std::bad_alloc& ba) {
1486 new G4PVPlacement(*t, logicSection, sectionName, topVolume,
false,
1488 }
catch (std::bad_alloc& ba) {
1491 return logicSection;
1497 G4LogicalVolume* logicLayer;
1498 const HepGeom::Transform3D* t;
1499 std::string layerName =
"Layer_" + std::to_string(
m_CurVol.layer) +
1500 "_" + section->GetName();
1504 new G4PVPlacement(*t, logicLayer, logicLayer->GetName(), section,
false,
1506 }
catch (std::bad_alloc& ba) {
1515 G4LogicalVolume* logicSector;
1516 const HepGeom::Transform3D* t;
1517 std::string sectorName =
"Sector_" + std::to_string(
m_CurVol.sector) +
1518 "_" + layer->GetName();
1523 new G4PVPlacement(*t, logicSector, logicSector->GetName(), layer,
false,
1525 }
catch (std::bad_alloc& ba) {
1535 HepGeom::Transform3D t;
1539 m_GeoDat->getSectorSupportPosition();
1543 t = HepGeom::Translate3D(0., 0., z);
1545 G4LogicalVolume* lv =
m_LogVol.cover;
1546 new G4PVPlacement(t, lv, lv->GetName() +
"_" + sector->GetName(), sector,
1548 }
catch (std::bad_alloc& ba) {
1556 HepGeom::Transform3D t;
1558 m_GeoDat->getSectorSupportGeometry();
1559 t = HepGeom::Translate3D(0., 0., sectorSupportGeometry->
getCorner1Z());
1561 G4LogicalVolume* lv =
m_LogVol.sectorsup.corn1;
1562 new G4PVPlacement(t, lv, lv->GetName() +
"_" + sector->GetName(), sector,
1564 }
catch (std::bad_alloc& ba) {
1572 HepGeom::Transform3D t;
1574 m_GeoDat->getSectorSupportGeometry();
1575 t = HepGeom::Translate3D(sectorSupportGeometry->
getCorner2Inner().x(),
1579 G4LogicalVolume* lv =
m_LogVol.sectorsup.corn2;
1580 new G4PVPlacement(t, lv, lv->GetName() +
"_" + sector->GetName(), sector,
1582 }
catch (std::bad_alloc& ba) {
1590 HepGeom::Transform3D t;
1592 m_GeoDat->getSectorSupportGeometry();
1593 t = HepGeom::Translate3D(sectorSupportGeometry->
getCorner3Prism().x(),
1597 G4LogicalVolume* lv =
m_LogVol.sectorsup.corn3;
1598 new G4PVPlacement(t, lv, lv->GetName() +
"_" + sector->GetName(), sector,
1600 }
catch (std::bad_alloc& ba) {
1608 HepGeom::Transform3D t;
1610 m_GeoDat->getSectorSupportGeometry();
1611 t = HepGeom::Translate3D(sectorSupportGeometry->
getCorner4Prism().x(),
1615 G4LogicalVolume* lv =
m_LogVol.sectorsup.corn4;
1616 new G4PVPlacement(t, lv, lv->GetName() +
"_" + sector->GetName(), sector,
1618 }
catch (std::bad_alloc& ba) {
1626 HepGeom::Transform3D t;
1628 m_GeoDat->getSectorSupportPosition();
1629 t = HepGeom::Translate3D(0., 0., sectorSupportPos->
getZ());
1631 G4LogicalVolume* lv =
m_LogVol.sectorsup.supp;
1632 new G4PVPlacement(t, lv, lv->GetName() +
"_" + sector->GetName(), sector,
1634 }
catch (std::bad_alloc& ba) {
1642 G4LogicalVolume* logicPlane =
nullptr;
1643 const HepGeom::Transform3D* t;
1644 std::string planeName =
1645 "Plane_" + std::to_string(
m_CurVol.plane) +
"_" + sector->GetName();
1649 }
catch (std::bad_alloc& ba) {
1656 new G4PVPlacement(*t, logicPlane, planeName, sector,
false,
1658 }
catch (std::bad_alloc& ba) {
1667 HepGeom::Transform3D t;
1668 G4LogicalVolume* lv =
1674 HepGeom::Translate3D(
1677 segmentSupportPos->
getX(), segmentSupportPos->
getY(),
1678 segmentSupportPos->
getZ()) *
1679 HepGeom::RotateX3D(180.0 * CLHEP::deg);
1681 new G4PVPlacement(t, lv, lv->GetName() +
"_" + plane->GetName(), plane,
1683 }
catch (std::bad_alloc& ba) {
1691 HepGeom::Transform3D t;
1693 m_GeoDat->getPlasticSheetGeometry();
1696 std::string sheetName =
1697 "Sheet_" + std::to_string(iSheet) +
1698 "_SheetPlane_" + std::to_string(iSheetPlane);
1700 if (iSheetPlane == 2)
1702 t = HepGeom::Translate3D(0, 0, z);
1704 new G4PVPlacement(t,
m_LogVol.psheet[iSheet - 1], sheetName,
1705 m_LogVol.segment[iSheet - 1],
false, (iSheetPlane - 1) *
1706 m_GeoDat->getNSegments() + iSheet,
false);
1707 }
catch (std::bad_alloc& ba) {
1714 HepGeom::Transform3D t;
1715 std::string segmentName =
"StripSegment_" + std::to_string(iSegment);
1716 t = HepGeom::Translate3D(0, 0, 0);
1718 new G4PVPlacement(t,
m_LogVol.stripSegment[iSegment - 1], segmentName,
1719 m_LogVol.segment[iSegment - 1],
false, iSegment,
false);
1720 }
catch (std::bad_alloc& ba) {
1727 HepGeom::Transform3D t;
1728 std::string segmentName =
1729 "Segment_" + std::to_string(
m_CurVol.segment) +
"_" + plane->GetName();
1737 plane,
false,
m_CurVol.segment,
false);
1738 }
catch (std::bad_alloc& ba) {
1746 HepGeom::Transform3D t, t2;
1747 G4LogicalVolume* lv;
1750 t2 = t * HepGeom::RotateX3D(180.0 * CLHEP::deg);
1753 new G4PVPlacement(t2, lv, lv->GetName(), segment,
false,
m_CurVol.strip,
1755 }
catch (std::bad_alloc& ba) {
1762 HepGeom::Transform3D t;
1763 G4LogicalVolume* lv;
1764 G4LogicalVolume* lvm;
1767 t = HepGeom::Translate3D(0., 0., 0.5 * (stripGeometry->
getThickness() -
1772 new G4PVPlacement(t, lv, lv->GetName(), lvm,
false, 1,
false);
1773 }
catch (std::bad_alloc& ba) {
1780 HepGeom::Transform3D t;
1781 G4LogicalVolume* lv;
1782 G4LogicalVolume* lvm;
1783 t = HepGeom::Translate3D(0., 0., 0.);
1787 new G4PVPlacement(t, lv, lv->GetName(), lvm,
false, 1,
false);
1788 }
catch (std::bad_alloc& ba) {
1795 HepGeom::Transform3D ta, tb, tc, td, te;
1796 G4LogicalVolume* lv;
1798 const double asqrt2 = 1.0 /
sqrt(2.0);
1805 HepGeom::RotateZ3D(-45.0 * CLHEP::deg);
1808 HepGeom::RotateZ3D(-45.0 * CLHEP::deg);
1811 HepGeom::RotateZ3D(-45.0 * CLHEP::deg) *
1812 HepGeom::RotateY3D(180.0 * CLHEP::deg);
1813 td = HepGeom::Translate3D(
1816 HepGeom::RotateZ3D(-45.0 * CLHEP::deg) *
1817 HepGeom::RotateX3D(180.0 * CLHEP::deg);
1818 te = HepGeom::Translate3D(
1821 HepGeom::RotateZ3D(135.0 * CLHEP::deg);
1824 new G4PVPlacement(ta, lv, lv->GetName(), sector,
false, 1,
false);
1825 }
catch (std::bad_alloc& ba) {
1830 new G4PVPlacement(tb, lv, lv->GetName(), sector,
false, 1,
false);
1831 }
catch (std::bad_alloc& ba) {
1836 new G4PVPlacement(tc, lv, lv->GetName(), sector,
false, 1,
false);
1837 }
catch (std::bad_alloc& ba) {
1842 new G4PVPlacement(td, lv, lv->GetName(), sector,
false, 1,
false);
1843 }
catch (std::bad_alloc& ba) {
1847 new G4PVPlacement(te, lv,
"ShieldDetailE", sector,
false, 1,
false);
1848 }
catch (std::bad_alloc& ba) {
1855 return ((section == 1 && layer <= m_GeoDat->getNDetectorLayers(1)) ||
1856 (section == 2 && layer <= m_GeoDat->getNDetectorLayers(2)));
1862 int i, j, imin, imax;
1863 G4LogicalVolume* section, *layer, *sector, *plane;
1867 for (i = 0; i <
m_GeoDat->getNStripsDifferentLength(); i++) {
1871 for (i = 0; i <
m_GeoDat->getNSegments(); i++) {
1877 for (i = 1; i <=
m_GeoDat->getNSegments(); i++) {
1878 for (j = 1; j <= 2; j++)
1884 G4Region* aRegion = 0;
1889 if (not aRegion) aRegion =
new G4Region(
"EKLMEnvelope");
1890 section->SetRegion(aRegion);
1891 aRegion->AddRootLogicalVolume(section);
1903 for (i = 1; i <= 2; i++)
1910 for (i = 1; i <=
m_GeoDat->getNSegments() + 1; i++)
1927 G4LogicalVolume& topVolume,
1936 }
catch (std::bad_alloc& ba) {
1945 G4LogicalVolume& topVolume,
1954 }
catch (std::bad_alloc& ba) {
1970 }
catch (std::bad_alloc& ba) {
static const EKLMElementNumbers & Instance()
Instantiation.
Position information for the elements of detector.
double getX() const
Get X coordinate.
double getOuterR() const
Get outer radius.
double getInnerR() const
Get inner radius.
double getZ() const
Get Z coordinate.
double getY() const
Get Y coordinate.
double getLength() const
Get length.
Endcap srtucture geometry parameters.
double getPhi() const
Get starting angle of the octagonal endcap structure shape.
int getNSides() const
Get number of sides.
Plastic sheet geometry data.
double getWidth() const
Get width.
double getDeltaL() const
Get Delta L (edge of last strip - edge of plastic sheet distance).
double getX() const
Get X coordinate.
double getY() const
Get Y coordinate.
Sector support geometry data.
double getCorner2Thickness() const
Get corner 2 thickness.
double getCorner2LY() const
Get corner 2 Y length.
double getCorner4Thickness() const
Get corner 4 thickness.
double getCorner1Z() const
Get corner 1 Z coordinate.
double getCornerX() const
Get coordinate X of corner 1.
double getCorner4LX() const
Get corner 4 X length.
double getCorner1LX() const
Get corner 1 X length.
double getCorner3LX() const
Get corner 3 X length.
const HepGeom::Point3D< double > & getCorner1B() const
Get corner 1B coordinates.
double getCornerAngle() const
Get corner 1 angle.
double getCorner4LY() const
Get corner 4 Y length.
const HepGeom::Point3D< double > & getCorner3Prism() const
Get coordinates of the corner of corner 3 prism.
const HepGeom::Point3D< double > & getCorner4() const
Get corner 4 coordinates.
double getCorner2LX() const
Get corner 2 X length.
const HepGeom::Point3D< double > & getCorner4Prism() const
Get coordinates of the corner of corner 4 prism.
double getThickness() const
Get thickness.
const HepGeom::Point3D< double > & getCorner3() const
Get corner 3 coordinates.
double getCorner4Z() const
Get corner 4 Z coordinate.
double getCorner3Z() const
Get corner 3 Z coordinate.
const HepGeom::Point3D< double > & getCorner1A() const
Get corner 1A coordinates.
double getCorner3Thickness() const
Get corner 3 thickness.
double getDeltaLY() const
Get outerR - Y of upper edge of BoxY.
const HepGeom::Point3D< double > & getCorner1AInner() const
Get corner 1A coordinates (inner side).
const HepGeom::Point3D< double > & getCorner2Inner() const
Get corner 2 coordinates (inner side).
double getCorner3LY() const
Get corner 3 Y length.
double getCorner1Width() const
Get corner 1 width.
double getCorner1Thickness() const
Get corner 1 thickness.
double getCorner2Z() const
Get corner 2 Z coordinate.
Segment support geometry data.
double getMiddleWidth() const
Get middle part width.
double getTopThickness() const
Get top part thickness.
double getTopWidth() const
Get top part width.
double getMiddleThickness() const
Get middle part thickness.
Segment support position.
double getX() const
Get X coordinate.
double getZ() const
Get Z coordinate.
double getY() const
Get Y coordinate.
double getDeltaLRight() const
Get right Delta L.
double getDeltaLLeft() const
Get left Delta L.
double getLength() const
Get length.
Shield layer detail geometry data.
const Point * getPoint(int i) const
Get point.
double getLengthY() const
Get Y length.
double getLengthX() const
Get X length.
Shield layer geometry data.
const ShieldDetailGeometry * getDetailA() const
Get detail A geometry.
const ShieldDetailGeometry * getDetailB() const
Get detail B geometry.
const Point * getDetailCCenter() const
Get detail C center.
double getThickness() const
Get thickness.
const ShieldDetailGeometry * getDetailD() const
Get detail D geometry.
const Point * getDetailACenter() const
Get detail A center.
const Point * getDetailBCenter() const
Get detail B center.
const ShieldDetailGeometry * getDetailC() const
Get detail C geometry.
double getWidth() const
Get width.
double getNoScintillationThickness() const
Get nonscintillating layer thickness.
double getGrooveDepth() const
Get groove depth.
double getThickness() const
Get thickness.
double getGrooveWidth() const
Get groove width.
~GeoEKLMCreator() override
Destructor.
GeoEKLMCreator()
Constructor.
G4Box * createSectorSupportBoxY(G4Transform3D &t)
Create Y side of sector support structure.
struct Solids m_Solids
Solids.
void createShieldDetailDLogicalVolume()
Create shield detail D logical volume.
void createShieldDetailALogicalVolume()
Create shield detail A logical volume.
void createShieldDetailCLogicalVolume()
Create shield detail C logical volume.
void createSegment(G4LogicalVolume *plane) const
Create segment (strips + plastic sheets).
void createMaterials()
Creation of materials.
G4Tubs * createSectorSupportOuterTube()
Create outer tube of sector support structure.
struct LogicalVolumes m_LogVol
Logical volumes.
TransformData * m_TransformData
Transformation data.
struct VolumeNumbers m_CurVol
Current volumes.
void createSectorSupportCorner4(G4LogicalVolume *sector) const
Create sector support corner 4.
struct Materials m_Materials
Materials.
void createShieldDetailBLogicalVolume()
Create shield detail B logical volume.
void createScintillator(int iStrip) const
Create scintillator.
G4LogicalVolume * createSection(G4LogicalVolume *topVolume) const
Create section.
void createSectorSupportCorner1LogicalVolume()
Create sector support corner 1 logical volume.
void createFromDB(const std::string &name, G4LogicalVolume &topVolume, geometry::GeometryTypes type) override
Creation of the detector geometry from database.
KLM::SensitiveDetector * m_Sensitive
Sensitive detector.
G4LogicalVolume * createSector(G4LogicalVolume *layer) const
Create sector.
void createPlaneSolid(int n)
Create plane solid.
static G4SubtractionSolid * cutSolidCorner(const char *name, G4VSolid *solid, G4Box *subtractionBox, const HepGeom::Transform3D &transf, bool largerAngles, double x1, double y1, double x2, double y2)
Cut corner of a solid.
void createSectorSupportCorner2LogicalVolume()
Create sector support corner 2 logical volume.
void newVolumes()
Create new volumes.
void createSubtractionBoxSolid()
Create subtraction box solid.
G4Box * createSectorSupportBoxTop(G4Transform3D &t)
Create box in the cutted corner of sector support structure.
void newSensitive()
Create new sensitive detectors.
void createSectorSupportCorner1(G4LogicalVolume *sector) const
Create sector support corner 1.
void createSectorSupportCorner3(G4LogicalVolume *sector) const
Create sector support corner 3.
void deleteSensitive()
Delete sensitive detectors.
G4LogicalVolume * createLayerLogicalVolume(const char *name) const
Create layer logical volume.
void createPayloads(const GearDir &content, const IntervalOfValidity &iov) override
Creation of payloads.
void createSectorCover(int iCover, G4LogicalVolume *sector) const
Create sector cover.
void createStripSegment(int iSegment) const
Create strip segment.
G4LogicalVolume * createPlane(G4LogicalVolume *sector) const
Create plane.
void createScintillatorLogicalVolume(int iStrip)
Create scintillator logical volume.
void createSegmentSupportLogicalVolume(int iPlane, int iSegmentSupport)
Create segment support logical volume.
void createShield(G4LogicalVolume *sector) const
Create shield.
void createPlasticSheet(int iSheetPlane, int iSheet) const
Create plastic sheet.
const EKLMElementNumbers * m_ElementNumbers
Element numbers.
void createSectorSupportCorner4LogicalVolume()
Create sector support corner 4 logical volume.
void createSegmentLogicalVolume(int iSegment)
Create segment logical volume (strips + plastic sheets).
void createSolids()
Create solids (or logical volumes which must be created only once).
void createPlasticSheetLogicalVolume(int iSegment)
Create plastic sheet logical volume.
void createSectorSupportLogicalVolume()
Create sector support logical volume.
void createLayerSolid()
Create layer solid.
G4Box * createSectorSupportBoxX(G4Transform3D &t)
Create X side of sector support structure.
void createSectorCoverLogicalVolume()
Create sector cover solid.
void createSectorSupportCorner2(G4LogicalVolume *sector) const
Create sector support corner 2.
void createStripGrooveLogicalVolume(int iStrip)
Create strip groove logical volume.
bool detectorLayer(int section, int layer) const
Check if a given layer is a detector layer.
void createStripGroove(int iStrip) const
Create strip groove.
void createSectorSupportCorner3LogicalVolume()
Create sector support corner 3 logical volume.
G4LogicalVolume * createLayer(G4LogicalVolume *section) const
Create layer.
static G4VSolid * unifySolids(G4VSolid **solids, HepGeom::Transform3D *transf, int nSolids, const std::string &name)
Unify a group of solids.
void createSectionSolid()
Create section solid.
G4LogicalVolume * createSectorLogicalVolume(const char *name) const
Create sector logical volume.
void createStrip(G4LogicalVolume *segment) const
Create strip.
void createSectorSolid()
Create sector solid.
void createStripLogicalVolume(int iStrip)
Create strip logical volume.
void deleteVolumes()
Delete volumes.
void create(const GearDir &content, G4LogicalVolume &topVolume, geometry::GeometryTypes type) override
Creation of the detector geometry from Gearbox (XML).
void createSectorSupport(G4LogicalVolume *sector) const
Create sector support structure (main part without corners).
const GeometryData * m_GeoDat
Geometry data.
void createStripSegmentLogicalVolume(int iSegment)
Create strip segment logical volume.
void createSegmentSupport(int iSegmentSupport, G4LogicalVolume *plane) const
Create segment support.
G4Tubs * createSectorSupportInnerTube()
Create inner tube of sector support structure.
static const GeometryData & Instance(enum DataSource dataSource=c_Database, const GearDir *gearDir=nullptr)
Instantiation.
@ c_Gearbox
Gearbox (XML).
G4VSolid * getSolid()
Get solid.
GearDir is the basic class used for accessing the parameter store.
A class that describes the interval of experiments/runs for which an object in the database is valid.
KLM sensitive-detector class.
static G4Material * get(const std::string &name)
Find given material.
double tan(double a)
tan for double
double sqrt(double a)
sqrt for double
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.
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.