File indexing completed on 2025-01-18 09:14:29
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <DD4hep/Shapes.h>
0016 #include <DD4hep/Printout.h>
0017 #include <DD4hep/detail/ShapesInterna.h>
0018
0019 #include "Geant4ShapeConverter.h"
0020
0021
0022 #include <TClass.h>
0023 #include <TGeoMatrix.h>
0024 #include <TGeoBoolNode.h>
0025 #include <TGeoScaledShape.h>
0026
0027
0028 #include <G4Box.hh>
0029 #include <G4Trd.hh>
0030 #include <G4Tubs.hh>
0031 #include <G4Trap.hh>
0032 #include <G4Cons.hh>
0033 #include <G4Hype.hh>
0034 #include <G4Para.hh>
0035 #include <G4Torus.hh>
0036 #include <G4Sphere.hh>
0037 #include <G4CutTubs.hh>
0038 #include <G4Polycone.hh>
0039 #include <G4Polyhedra.hh>
0040 #include <G4Ellipsoid.hh>
0041 #include <G4Paraboloid.hh>
0042 #include <G4TwistedTubs.hh>
0043 #include <G4GenericTrap.hh>
0044 #include <G4ExtrudedSolid.hh>
0045 #include <G4EllipticalTube.hh>
0046 #include <G4TessellatedSolid.hh>
0047 #include <G4TriangularFacet.hh>
0048 #include <G4QuadrangularFacet.hh>
0049
0050
0051
0052 using namespace dd4hep::detail;
0053
0054
0055 namespace dd4hep {
0056
0057
0058 namespace sim {
0059
0060 static const double CM_2_MM = (CLHEP::centimeter/dd4hep::centimeter);
0061
0062
0063 template <typename T> G4VSolid* convertShape(const TGeoShape* shape) {
0064 if ( shape ) {
0065 except("convertShape","Unsupported shape: %s",shape->IsA()->GetName());
0066 }
0067 except("convertShape","Invalid shape conversion requested.");
0068 return 0;
0069 }
0070
0071 template <> G4VSolid* convertShape<TGeoShapeAssembly>(const TGeoShape* ) {
0072 return 0;
0073 }
0074
0075 template <> G4VSolid* convertShape<TGeoBBox>(const TGeoShape* shape) {
0076 const TGeoBBox* sh = (const TGeoBBox*) shape;
0077 return new G4Box(sh->GetName(), sh->GetDX() * CM_2_MM, sh->GetDY() * CM_2_MM, sh->GetDZ() * CM_2_MM);
0078 }
0079
0080 template <> G4VSolid* convertShape<TGeoTube>(const TGeoShape* shape) {
0081 const TGeoTube* sh = (const TGeoTube*) shape;
0082 return new G4Tubs(sh->GetName(), sh->GetRmin() * CM_2_MM, sh->GetRmax() * CM_2_MM, sh->GetDz() * CM_2_MM, 0, 2. * M_PI);
0083 }
0084
0085 template <> G4VSolid* convertShape<TGeoTubeSeg>(const TGeoShape* shape) {
0086 const TGeoTubeSeg* sh = (const TGeoTubeSeg*) shape;
0087 return new G4Tubs(sh->GetName(), sh->GetRmin() * CM_2_MM, sh->GetRmax() * CM_2_MM, sh->GetDz() * CM_2_MM,
0088 sh->GetPhi1() * DEGREE_2_RAD, (sh->GetPhi2()-sh->GetPhi1()) * DEGREE_2_RAD);
0089 }
0090
0091 template <> G4VSolid* convertShape<TGeoCtub>(const TGeoShape* shape) {
0092 const TGeoCtub* sh = (const TGeoCtub*) shape;
0093 const Double_t* ln = sh->GetNlow();
0094 const Double_t* hn = sh->GetNhigh();
0095 G4ThreeVector lowNorm (ln[0], ln[1], ln[2]);
0096 G4ThreeVector highNorm(hn[0], hn[1], hn[2]);
0097 return new G4CutTubs(sh->GetName(),
0098 sh->GetRmin() * CM_2_MM, sh->GetRmax() * CM_2_MM, sh->GetDz() * CM_2_MM,
0099 sh->GetPhi1() * DEGREE_2_RAD, (sh->GetPhi2()-sh->GetPhi1()) * DEGREE_2_RAD,
0100 std::move(lowNorm), std::move(highNorm));
0101 }
0102
0103 template <> G4VSolid* convertShape<TGeoEltu>(const TGeoShape* shape) {
0104 const TGeoEltu* sh = (const TGeoEltu*) shape;
0105 return new G4EllipticalTube(sh->GetName(),sh->GetA() * CM_2_MM, sh->GetB() * CM_2_MM, sh->GetDz() * CM_2_MM);
0106 }
0107
0108 template <> G4VSolid* convertShape<TwistedTubeObject>(const TGeoShape* shape) {
0109 const TwistedTubeObject* sh = (const TwistedTubeObject*) shape;
0110 if ( std::fabs(std::fabs(sh->GetNegativeEndZ()) - std::fabs(sh->GetPositiveEndZ())) < 1e-10 ) {
0111 return new G4TwistedTubs(sh->GetName(),sh->GetPhiTwist() * DEGREE_2_RAD,
0112 sh->GetRmin() * CM_2_MM, sh->GetRmax() * CM_2_MM,
0113 sh->GetPositiveEndZ() * CM_2_MM,
0114 sh->GetNsegments(),
0115 (sh->GetPhi2()-sh->GetPhi1()) * DEGREE_2_RAD);
0116 }
0117 return new G4TwistedTubs(sh->GetName(),sh->GetPhiTwist() * DEGREE_2_RAD,
0118 sh->GetRmin() * CM_2_MM, sh->GetRmax() * CM_2_MM,
0119 sh->GetNegativeEndZ() * CM_2_MM, sh->GetPositiveEndZ() * CM_2_MM,
0120 sh->GetNsegments(),
0121 (sh->GetPhi2()-sh->GetPhi1()) * DEGREE_2_RAD);
0122 }
0123
0124 template <> G4VSolid* convertShape<TGeoTrd1>(const TGeoShape* shape) {
0125 const TGeoTrd1* sh = (const TGeoTrd1*) shape;
0126 return new G4Trd(sh->GetName(),
0127 sh->GetDx1() * CM_2_MM, sh->GetDx2() * CM_2_MM,
0128 sh->GetDy() * CM_2_MM, sh->GetDy() * CM_2_MM,
0129 sh->GetDz() * CM_2_MM);
0130 }
0131
0132 template <> G4VSolid* convertShape<TGeoTrd2>(const TGeoShape* shape) {
0133 const TGeoTrd2* sh = (const TGeoTrd2*) shape;
0134 return new G4Trd(sh->GetName(),
0135 sh->GetDx1() * CM_2_MM, sh->GetDx2() * CM_2_MM,
0136 sh->GetDy1() * CM_2_MM, sh->GetDy2() * CM_2_MM,
0137 sh->GetDz() * CM_2_MM);
0138 }
0139
0140 template <> G4VSolid* convertShape<TGeoHype>(const TGeoShape* shape) {
0141 const TGeoHype* sh = (const TGeoHype*) shape;
0142 return new G4Hype(sh->GetName(), sh->GetRmin() * CM_2_MM, sh->GetRmax() * CM_2_MM,
0143 sh->GetStIn() * DEGREE_2_RAD, sh->GetStOut() * DEGREE_2_RAD,
0144 sh->GetDz() * CM_2_MM);
0145 }
0146
0147 template <> G4VSolid* convertShape<TGeoArb8>(const TGeoShape* shape) {
0148 std::vector<G4TwoVector> vertices;
0149 TGeoArb8* sh = (TGeoArb8*) shape;
0150 Double_t* vtx_xy = sh->GetVertices();
0151 for ( std::size_t i=0; i<8; ++i, vtx_xy +=2 )
0152 vertices.emplace_back(vtx_xy[0] * CM_2_MM, vtx_xy[1] * CM_2_MM);
0153 return new G4GenericTrap(sh->GetName(), sh->GetDz() * CM_2_MM, vertices);
0154 }
0155
0156 template <> G4VSolid* convertShape<TGeoPara>(const TGeoShape* shape) {
0157 const auto* sh = static_cast<const TGeoPara*>(shape);
0158 return new G4Para(sh->GetName(),
0159 sh->GetX() * CM_2_MM, sh->GetY() * CM_2_MM, sh->GetZ() * CM_2_MM,
0160 sh->GetAlpha() * DEGREE_2_RAD, sh->GetTheta() * DEGREE_2_RAD,
0161 sh->GetPhi() * DEGREE_2_RAD);
0162 }
0163
0164 template <> G4VSolid* convertShape<TGeoXtru>(const TGeoShape* shape) {
0165 const TGeoXtru* sh = (const TGeoXtru*) shape;
0166 std::size_t nz = sh->GetNz();
0167 std::vector<G4ExtrudedSolid::ZSection> z;
0168 z.reserve(nz);
0169 for(std::size_t i=0; i<nz; ++i) {
0170 z.emplace_back(G4ExtrudedSolid::ZSection(sh->GetZ(i) * CM_2_MM, {sh->GetXOffset(i), sh->GetYOffset(i)}, sh->GetScale(i)));
0171 }
0172 std::size_t np = sh->GetNvert();
0173 std::vector<G4TwoVector> polygon;
0174 polygon.reserve(np);
0175 for(std::size_t i=0; i<np; ++i) {
0176 polygon.emplace_back(sh->GetX(i) * CM_2_MM,sh->GetY(i) * CM_2_MM);
0177 }
0178 return new G4ExtrudedSolid(sh->GetName(), polygon, z);
0179 }
0180
0181 template <> G4VSolid* convertShape<TGeoPgon>(const TGeoShape* shape) {
0182 const TGeoPgon* sh = (const TGeoPgon*) shape;
0183 std::vector<double> rmin, rmax, z;
0184 for (Int_t i = 0; i < sh->GetNz(); ++i) {
0185 rmin.emplace_back(sh->GetRmin(i) * CM_2_MM);
0186 rmax.emplace_back(sh->GetRmax(i) * CM_2_MM);
0187 z.emplace_back(sh->GetZ(i) * CM_2_MM);
0188 }
0189 return new G4Polyhedra(sh->GetName(), sh->GetPhi1() * DEGREE_2_RAD, sh->GetDphi() * DEGREE_2_RAD,
0190 sh->GetNedges(), sh->GetNz(), &z[0], &rmin[0], &rmax[0]);
0191 }
0192
0193 template <> G4VSolid* convertShape<TGeoPcon>(const TGeoShape* shape) {
0194 const TGeoPcon* sh = (const TGeoPcon*) shape;
0195 std::vector<double> rmin, rmax, z;
0196 for (Int_t i = 0; i < sh->GetNz(); ++i) {
0197 rmin.emplace_back(sh->GetRmin(i) * CM_2_MM);
0198 rmax.emplace_back(sh->GetRmax(i) * CM_2_MM);
0199 z.emplace_back(sh->GetZ(i) * CM_2_MM);
0200 }
0201 return new G4Polycone(sh->GetName(), sh->GetPhi1() * DEGREE_2_RAD, sh->GetDphi() * DEGREE_2_RAD,
0202 sh->GetNz(), &z[0], &rmin[0], &rmax[0]);
0203 }
0204
0205 template <> G4VSolid* convertShape<TGeoCone>(const TGeoShape* shape) {
0206 const TGeoCone* sh = (const TGeoCone*) shape;
0207 return new G4Cons(sh->GetName(), sh->GetRmin1() * CM_2_MM, sh->GetRmax1() * CM_2_MM, sh->GetRmin2() * CM_2_MM,
0208 sh->GetRmax2() * CM_2_MM, sh->GetDz() * CM_2_MM, 0.0, 2.*M_PI);
0209 }
0210
0211 template <> G4VSolid* convertShape<TGeoConeSeg>(const TGeoShape* shape) {
0212 const TGeoConeSeg* sh = (const TGeoConeSeg*) shape;
0213 return new G4Cons(sh->GetName(), sh->GetRmin1() * CM_2_MM, sh->GetRmax1() * CM_2_MM,
0214 sh->GetRmin2() * CM_2_MM, sh->GetRmax2() * CM_2_MM,
0215 sh->GetDz() * CM_2_MM,
0216 sh->GetPhi1() * DEGREE_2_RAD, (sh->GetPhi2()-sh->GetPhi1()) * DEGREE_2_RAD);
0217 }
0218
0219 template <> G4VSolid* convertShape<TGeoParaboloid>(const TGeoShape* shape) {
0220 const TGeoParaboloid* sh = (const TGeoParaboloid*) shape;
0221 return new G4Paraboloid(sh->GetName(), sh->GetDz() * CM_2_MM, sh->GetRlo() * CM_2_MM, sh->GetRhi() * CM_2_MM);
0222 }
0223
0224 template <> G4VSolid* convertShape<TGeoSphere>(const TGeoShape* shape) {
0225 const TGeoSphere* sh = (const TGeoSphere*) shape;
0226 return new G4Sphere(sh->GetName(), sh->GetRmin() * CM_2_MM, sh->GetRmax() * CM_2_MM,
0227 sh->GetPhi1() * DEGREE_2_RAD, (sh->GetPhi2()-sh->GetPhi1()) * DEGREE_2_RAD,
0228 sh->GetTheta1() * DEGREE_2_RAD, (sh->GetTheta2()- sh->GetTheta1()) * DEGREE_2_RAD);
0229 }
0230
0231 template <> G4VSolid* convertShape<TGeoTorus>(const TGeoShape* shape) {
0232 const TGeoTorus* sh = (const TGeoTorus*) shape;
0233 return new G4Torus(sh->GetName(), sh->GetRmin() * CM_2_MM, sh->GetRmax() * CM_2_MM, sh->GetR() * CM_2_MM,
0234 sh->GetPhi1() * DEGREE_2_RAD, sh->GetDphi() * DEGREE_2_RAD);
0235 }
0236
0237 template <> G4VSolid* convertShape<TGeoTrap>(const TGeoShape* shape) {
0238 const TGeoTrap* sh = (const TGeoTrap*) shape;
0239 return new G4Trap(sh->GetName(), sh->GetDz() * CM_2_MM, sh->GetTheta() * DEGREE_2_RAD, sh->GetPhi() * DEGREE_2_RAD,
0240 sh->GetH1() * CM_2_MM, sh->GetBl1() * CM_2_MM, sh->GetTl1() * CM_2_MM, sh->GetAlpha1() * DEGREE_2_RAD,
0241 sh->GetH2() * CM_2_MM, sh->GetBl2() * CM_2_MM, sh->GetTl2() * CM_2_MM, sh->GetAlpha2() * DEGREE_2_RAD);
0242 }
0243
0244 template <> G4VSolid* convertShape<G4GenericTrap>(const TGeoShape* shape) {
0245 std::vector<G4TwoVector> vertices;
0246 TGeoTrap* sh = (TGeoTrap*) shape;
0247 Double_t* vtx_xy = sh->GetVertices();
0248 for ( std::size_t i=0; i<8; ++i, vtx_xy +=2 )
0249 vertices.emplace_back(vtx_xy[0] * CM_2_MM, vtx_xy[1] * CM_2_MM);
0250 return new G4GenericTrap(sh->GetName(), sh->GetDz() * CM_2_MM, vertices);
0251 }
0252
0253 template <> G4VSolid* convertShape<TGeoTessellated>(const TGeoShape* shape) {
0254 TGeoTessellated* sh = (TGeoTessellated*) shape;
0255 G4TessellatedSolid* g4 = new G4TessellatedSolid(sh->GetName());
0256 int num_facet = sh->GetNfacets();
0257
0258 printout(DEBUG,"TessellatedSolid","+++ %s> Converting %d facets", sh->GetName(), num_facet);
0259 for(int i=0; i<num_facet; ++i) {
0260 const TGeoFacet& facet = sh->GetFacet(i);
0261 int nv = facet.GetNvert();
0262 #if ROOT_VERSION_CODE >= ROOT_VERSION(6,31,1)
0263 const auto& v0 = sh->GetVertex(facet[0]);
0264 const auto& v1 = sh->GetVertex(facet[1]);
0265 const auto& v2 = sh->GetVertex(facet[2]);
0266 #else
0267 const auto& v0 = sh->GetVertex(facet.GetVertexIndex(0));
0268 const auto& v1 = sh->GetVertex(facet.GetVertexIndex(1));
0269 const auto& v2 = sh->GetVertex(facet.GetVertexIndex(2));
0270 #endif
0271 G4VFacet* g4f = 0;
0272 if ( nv == 3 ) {
0273 g4f = new G4TriangularFacet(G4ThreeVector(v0.x() * CM_2_MM, v0.y() * CM_2_MM, v0.z() * CM_2_MM),
0274 G4ThreeVector(v1.x() * CM_2_MM, v1.y() * CM_2_MM, v1.z() * CM_2_MM),
0275 G4ThreeVector(v2.x() * CM_2_MM, v2.y() * CM_2_MM, v2.z() * CM_2_MM),
0276 ABSOLUTE);
0277 }
0278 else if ( nv == 4 ) {
0279 #if ROOT_VERSION_CODE >= ROOT_VERSION(6,31,1)
0280 const auto& v3 = sh->GetVertex(facet[3]);
0281 #else
0282 const auto& v3 = sh->GetVertex(facet.GetVertexIndex(3));
0283 #endif
0284 g4f = new G4QuadrangularFacet(G4ThreeVector(v0.x() * CM_2_MM, v0.y() * CM_2_MM, v0.z() * CM_2_MM),
0285 G4ThreeVector(v1.x() * CM_2_MM, v1.y() * CM_2_MM, v1.z() * CM_2_MM),
0286 G4ThreeVector(v2.x() * CM_2_MM, v2.y() * CM_2_MM, v2.z() * CM_2_MM),
0287 G4ThreeVector(v3.x() * CM_2_MM, v3.y() * CM_2_MM, v3.z() * CM_2_MM),
0288 ABSOLUTE);
0289 }
0290 else {
0291 except("TGeoTessellated", "Tessellated shape [%s] has facet with wrong number of vertices: %d",
0292 sh->GetName(), nv);
0293 }
0294 g4->AddFacet(g4f);
0295 }
0296 g4->SetSolidClosed(sh->IsClosedBody());
0297 return g4;
0298 }
0299
0300 }
0301 }