35 #include "G4LogicalVolume.hh"
36 #include "G4Material.hh"
40 #include "G4VPhysicalVolume.hh"
41 #include "G4VSolid.hh"
44 const G4ThreeVector& g4Trans) {
45 Transform3 gTransform = Transform3::Identity();
48 gTransform.pretranslate(scaledTrans);
53 const G4RotationMatrix& g4Rot,
const G4ThreeVector& g4Trans) {
59 rotation << g4Rot.xx(), g4Rot.yx(), g4Rot.zx(), g4Rot.xy(), g4Rot.yy(),
60 g4Rot.zy(), g4Rot.xz(), g4Rot.yz(), g4Rot.zz();
62 transform.matrix().block(0, 0, 3, 1) = rotation.col(0);
63 transform.matrix().block(0, 1, 3, 1) = rotation.col(1);
64 transform.matrix().block(0, 2, 3, 1) = rotation.col(2);
70 const G4Transform3D& g4Trf) {
71 auto g4Rot = g4Trf.getRotation();
72 auto g4Trans = g4Trf.getTranslation();
79 auto g4Translation = g4PhysVol.GetTranslation();
80 auto g4Rotation = g4PhysVol.GetRotation();
82 G4Transform3D g4Transform =
83 (g4Rotation ==
nullptr)
84 ? G4Transform3D(CLHEP::HepRotation(), g4Translation)
85 : G4Transform3D(*g4Rotation, g4Translation);
94 std::array<Acts::ActsScalar, B::eSize> tArray = {};
96 g4Tubs.GetOuterRadius()) *
98 tArray[B::eHalfLengthZ] =
static_cast<ActsScalar>(g4Tubs.GetZHalfLength());
99 tArray[B::eHalfPhiSector] =
100 0.5 *
static_cast<ActsScalar>(g4Tubs.GetDeltaPhiAngle());
103 if (std::abs(tArray[B::eHalfPhiSector] - M_PI) <
104 std::numeric_limits<ActsScalar>::epsilon()) {
105 tArray[B::eAveragePhi] = 0.;
107 tArray[B::eAveragePhi] =
108 static_cast<ActsScalar>(g4Tubs.GetStartPhiAngle()) +
109 tArray[B::eHalfPhiSector];
112 auto cBounds = std::make_shared<CylinderBounds>(tArray);
120 std::array<ActsScalar, B::eSize> tArray = {};
121 tArray[B::eMinR] =
static_cast<ActsScalar>(g4Tubs.GetInnerRadius());
122 tArray[B::eMaxR] =
static_cast<ActsScalar>(g4Tubs.GetOuterRadius());
123 tArray[B::eHalfPhiSector] =
124 0.5 *
static_cast<ActsScalar>(g4Tubs.GetDeltaPhiAngle());
127 if (std::abs(tArray[B::eHalfPhiSector] - M_PI) <
128 std::numeric_limits<ActsScalar>::epsilon()) {
129 tArray[B::eAveragePhi] = 0.;
131 tArray[B::eAveragePhi] =
132 static_cast<ActsScalar>(g4Tubs.GetStartPhiAngle()) +
133 tArray[B::eHalfPhiSector];
136 auto rBounds = std::make_shared<RadialBounds>(tArray);
141 const G4Tubs& g4Tubs) {
142 auto r =
static_cast<ActsScalar>(g4Tubs.GetOuterRadius());
143 auto hlZ =
static_cast<ActsScalar>(g4Tubs.GetZHalfLength());
144 return std::make_shared<LineBounds>(
r, hlZ);
147 std::tuple<std::shared_ptr<Acts::RectangleBounds>, std::array<int, 2u>,
150 std::vector<ActsScalar> hG4XYZ = {
151 static_cast<ActsScalar>(g4Box.GetXHalfLength()),
152 static_cast<ActsScalar>(g4Box.GetYHalfLength()),
153 static_cast<ActsScalar>(g4Box.GetZHalfLength())};
155 auto minAt = std::min_element(hG4XYZ.begin(), hG4XYZ.end());
159 std::array<int, 2u> rAxes = {};
175 auto rBounds = std::make_shared<RectangleBounds>(hG4XYZ[std::abs(rAxes[0
u])],
176 hG4XYZ[std::abs(rAxes[1u])]);
180 std::tuple<std::shared_ptr<Acts::TrapezoidBounds>, std::array<int, 2u>,
190 std::vector<ActsScalar> dXYZ = {(hlX0 + hlX1) * 0.5, (hlY0 + hlY1) * 0.5,
193 auto minAt = std::min_element(dXYZ.begin(), dXYZ.end());
201 std::array<int, 2u> rAxes = {};
204 halfLengthXminY = hlY0;
205 halfLengthXmaxY = hlY1;
210 halfLengthXminY = hlX0;
211 halfLengthXmaxY = hlX1;
216 if (std::abs(hlY0 - hlY1) < std::abs(hlX0 - hlX1)) {
217 halfLengthXminY = hlX0;
218 halfLengthXmaxY = hlX1;
219 halfLengthY = (hlY0 + hlY1) * 0.5;
222 halfLengthXminY = hlY0;
223 halfLengthXmaxY = hlY1;
224 halfLengthY = (hlX0 + hlX1) * 0.5;
230 auto tBounds = std::make_shared<TrapezoidBounds>(
231 halfLengthXminY, halfLengthXmaxY, halfLengthY);
235 std::tuple<std::shared_ptr<Acts::PlanarBounds>, std::array<int, 2u>,
238 const G4Box*
box =
dynamic_cast<const G4Box*
>(&g4Solid);
239 if (box !=
nullptr) {
244 const G4Trd* trd =
dynamic_cast<const G4Trd*
>(&g4Solid);
245 if (trd !=
nullptr) {
246 auto [tBounds, axes,
thickness] = trapezoidBounds(*trd);
250 std::shared_ptr<Acts::PlanarBounds> pBounds =
nullptr;
251 std::array<int, 2u> rAxes = {};
258 const std::array<int, 2u>& axes) {
259 auto originalRotation = toGlobalOriginal.rotation();
260 auto colX = originalRotation.col(std::abs(axes[0
u]));
261 auto colY = originalRotation.col(std::abs(axes[1u]));
267 orientedTransform.matrix().block(0, 0, 3, 1) = colX;
268 orientedTransform.matrix().block(0, 1, 3, 1) = colY;
269 orientedTransform.matrix().block(0, 2, 3, 1) = colZ;
270 orientedTransform.matrix().block(0, 3, 3, 1) = toGlobalOriginal.translation();
272 return orientedTransform;
278 bool convertMaterial,
ActsScalar compressed) {
280 auto g4LogVol = g4PhysVol.GetLogicalVolume();
281 auto g4Solid = g4LogVol->GetSolid();
286 if (convertMaterial and
g4Material !=
nullptr) {
287 if (compressed < 0.) {
288 mcompressed = moriginal;
297 std::shared_ptr<Surface>
surface =
nullptr;
300 auto g4Box =
dynamic_cast<const G4Box*
>(g4Solid);
301 if (g4Box !=
nullptr) {
302 if (forcedType == Surface::SurfaceType::Other or
303 forcedType == Surface::SurfaceType::Plane) {
304 auto [
bounds, axes, original] =
306 auto orientedToGlobal = axesOriented(toGlobal, axes);
307 surface = Acts::Surface::makeShared<PlaneSurface>(orientedToGlobal,
309 assignMaterial(*surface.get(), original, compressed);
312 throw std::runtime_error(
"Can not convert 'G4Box' into forced shape.");
317 auto g4Trd =
dynamic_cast<const G4Trd*
>(g4Solid);
318 if (g4Trd !=
nullptr) {
319 if (forcedType == Surface::SurfaceType::Other or
320 forcedType == Surface::SurfaceType::Plane) {
321 auto [
bounds, axes, original] =
323 auto orientedToGlobal = axesOriented(toGlobal, axes);
324 surface = Acts::Surface::makeShared<PlaneSurface>(orientedToGlobal,
326 assignMaterial(*surface.get(), original, compressed);
329 throw std::runtime_error(
"Can not convert 'G4Trd' into forced shape.");
334 auto g4Tubs =
dynamic_cast<const G4Tubs*
>(g4Solid);
335 if (g4Tubs !=
nullptr) {
336 ActsScalar diffR = g4Tubs->GetOuterRadius() - g4Tubs->GetInnerRadius();
337 ActsScalar diffZ = 2 * g4Tubs->GetZHalfLength();
340 if (forcedType == Surface::SurfaceType::Cylinder or
341 (diffR < diffZ and forcedType == Surface::SurfaceType::Other)) {
343 original = originalT;
344 surface = Acts::Surface::makeShared<CylinderSurface>(toGlobal,
346 }
else if (forcedType == Surface::SurfaceType::Disc or
347 forcedType == Surface::SurfaceType::Other) {
349 original = originalT;
352 }
else if (forcedType == Surface::SurfaceType::Straw) {
358 throw std::runtime_error(
"Can not convert 'G4Tubs' into forced shape.");
360 assignMaterial(*surface.get(), original, compressed);
369 auto X0 = g4Material.GetRadlen();
370 auto L0 = g4Material.GetNuclearInterLength();
371 auto Rho = g4Material.GetDensity();
375 auto g4Elements = g4Material.GetElementVector();
376 auto g4Fraction = g4Material.GetFractionVector();
377 auto g4NElements = g4Material.GetNumberOfElements();
380 if (g4NElements == 1) {
381 Ar = g4Elements->at(0)->GetN();
382 Z = g4Material.GetZ();
384 for (
size_t i = 0;
i < g4NElements;
i++) {
385 Ar += g4Elements->at(
i)->GetN() * g4Fraction[
i];
386 Z += g4Elements->at(
i)->GetZ() * g4Fraction[
i];
394 std::shared_ptr<Acts::HomogeneousSurfaceMaterial>
398 ActsScalar compression = original / compressed;
399 return std::make_shared<HomogeneousSurfaceMaterial>(
403 std::shared_ptr<Acts::CylinderVolumeBounds>
407 std::array<Acts::ActsScalar, C::eSize> tArray = {};
408 tArray[C::eMinR] =
static_cast<ActsScalar>(g4Tubs.GetInnerRadius());
409 tArray[C::eMaxR] =
static_cast<ActsScalar>(g4Tubs.GetOuterRadius());
410 tArray[C::eHalfLengthZ] =
static_cast<ActsScalar>(g4Tubs.GetZHalfLength());
411 tArray[C::eHalfPhiSector] =
412 0.5 *
static_cast<ActsScalar>(g4Tubs.GetDeltaPhiAngle());
413 tArray[C::eAveragePhi] =
static_cast<ActsScalar>(g4Tubs.GetStartPhiAngle());
415 return std::make_shared<CylinderVolumeBounds>(tArray);