Skip to content

Commit

Permalink
refactor: geant4 converters (#2048)
Browse files Browse the repository at this point in the history
split off changes from my [calorimeter
demo](https://github.com/acts-project/acts/compare/main...andiwand:tmp-calorimeter-demo?expand=1).
this changes most of the shared pointers to unique pointers in the
converter because we use unique pointers downstream sometimes. and
unique pointers can be upgraded to shared pointers directly. it also
includes a generalization of the material conversion and transform
conversion

**update and summary**

- switched from `unique_ptr` consistently to `shared_ptr` after
discussion
- added `Geant4VolumeConverter`
- added transform translation for G4 phyiscal volumes
- added generic material translation

---------

Co-authored-by: Andreas Salzburger <asalzburger@gmail.com>
  • Loading branch information
andiwand and asalzburger committed May 8, 2023
1 parent 2e45ac2 commit 9a19dbc
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 56 deletions.
14 changes: 7 additions & 7 deletions Core/include/Acts/Detector/DetectorVolume.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ class DetectorVolume : public std::enable_shared_from_this<DetectorVolume> {
/// state updator delegates are not connected
DetectorVolume(
const GeometryContext& gctx, const std::string& name,
const Transform3& transform, std::unique_ptr<VolumeBounds> bounds,
const Transform3& transform, std::shared_ptr<VolumeBounds> bounds,
std::vector<std::shared_ptr<Surface>> surfaces,
std::vector<std::shared_ptr<DetectorVolume>> volumes,
DetectorVolumeUpdator&& detectorVolumeUpdator,
Expand All @@ -120,15 +120,15 @@ class DetectorVolume : public std::enable_shared_from_this<DetectorVolume> {
/// state updator delegates are not connected
DetectorVolume(
const GeometryContext& gctx, const std::string& name,
const Transform3& transform, std::unique_ptr<VolumeBounds> bounds,
const Transform3& transform, std::shared_ptr<VolumeBounds> bounds,
SurfaceCandidatesUpdator&& surfaceCandidateUpdator) noexcept(false);

/// Factory method for producing memory managed instances of DetectorVolume.
///
/// @note This is called by the @class DetectorVolumeFactory
static std::shared_ptr<DetectorVolume> makeShared(
const GeometryContext& gctx, const std::string& name,
const Transform3& transform, std::unique_ptr<VolumeBounds> bounds,
const Transform3& transform, std::shared_ptr<VolumeBounds> bounds,
std::vector<std::shared_ptr<Surface>> surfaces,
std::vector<std::shared_ptr<DetectorVolume>> volumes,
DetectorVolumeUpdator&& detectorVolumeUpdator,
Expand All @@ -139,7 +139,7 @@ class DetectorVolume : public std::enable_shared_from_this<DetectorVolume> {
/// @note This is called by the @class DetectorVolumeFactory
static std::shared_ptr<DetectorVolume> makeShared(
const GeometryContext& gctx, const std::string& name,
const Transform3& transform, std::unique_ptr<VolumeBounds> bounds,
const Transform3& transform, std::shared_ptr<VolumeBounds> bounds,
SurfaceCandidatesUpdator&& surfaceCandidateUpdator);

public:
Expand Down Expand Up @@ -362,7 +362,7 @@ class DetectorVolume : public std::enable_shared_from_this<DetectorVolume> {
Transform3 m_transform = Transform3::Identity();

/// Volume boundaries
std::unique_ptr<VolumeBounds> m_bounds = nullptr;
std::shared_ptr<VolumeBounds> m_bounds = nullptr;

/// Portal store (internal/external)
ObjectStore<std::shared_ptr<Portal>> m_portals;
Expand Down Expand Up @@ -400,7 +400,7 @@ class DetectorVolumeFactory {
static std::shared_ptr<DetectorVolume> construct(
const PortalGenerator& portalGenerator, const GeometryContext& gctx,
const std::string& name, const Transform3& transform,
std::unique_ptr<VolumeBounds> bounds,
std::shared_ptr<VolumeBounds> bounds,
const std::vector<std::shared_ptr<Surface>>& surfaces,
const std::vector<std::shared_ptr<DetectorVolume>>& volumes,
DetectorVolumeUpdator&& detectorVolumeUpdator,
Expand All @@ -416,7 +416,7 @@ class DetectorVolumeFactory {
static std::shared_ptr<DetectorVolume> construct(
const PortalGenerator& portalGenerator, const GeometryContext& gctx,
const std::string& name, const Transform3& transform,
std::unique_ptr<VolumeBounds> bounds,
std::shared_ptr<VolumeBounds> bounds,
SurfaceCandidatesUpdator&& surfaceCandidateUpdator) {
auto dVolume =
DetectorVolume::makeShared(gctx, name, transform, std::move(bounds),
Expand Down
8 changes: 4 additions & 4 deletions Core/src/Detector/DetectorVolume.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

Acts::Experimental::DetectorVolume::DetectorVolume(
const GeometryContext& gctx, const std::string& name,
const Transform3& transform, std::unique_ptr<VolumeBounds> bounds,
const Transform3& transform, std::shared_ptr<VolumeBounds> bounds,
std::vector<std::shared_ptr<Surface>> surfaces,
std::vector<std::shared_ptr<DetectorVolume>> volumes,
DetectorVolumeUpdator&& detectorVolumeUpdator,
Expand Down Expand Up @@ -53,15 +53,15 @@ Acts::Experimental::DetectorVolume::DetectorVolume(

Acts::Experimental::DetectorVolume::DetectorVolume(
const GeometryContext& gctx, const std::string& name,
const Transform3& transform, std::unique_ptr<VolumeBounds> bounds,
const Transform3& transform, std::shared_ptr<VolumeBounds> bounds,
SurfaceCandidatesUpdator&& surfaceCandidateUpdator)
: DetectorVolume(gctx, name, transform, std::move(bounds), {}, {},
tryNoVolumes(), std::move(surfaceCandidateUpdator)) {}

std::shared_ptr<Acts::Experimental::DetectorVolume>
Acts::Experimental::DetectorVolume::makeShared(
const GeometryContext& gctx, const std::string& name,
const Transform3& transform, std::unique_ptr<VolumeBounds> bounds,
const Transform3& transform, std::shared_ptr<VolumeBounds> bounds,
std::vector<std::shared_ptr<Surface>> surfaces,
std::vector<std::shared_ptr<DetectorVolume>> volumes,
DetectorVolumeUpdator&& detectorVolumeUpdator,
Expand All @@ -75,7 +75,7 @@ Acts::Experimental::DetectorVolume::makeShared(
std::shared_ptr<Acts::Experimental::DetectorVolume>
Acts::Experimental::DetectorVolume::makeShared(
const GeometryContext& gctx, const std::string& name,
const Transform3& transform, std::unique_ptr<VolumeBounds> bounds,
const Transform3& transform, std::shared_ptr<VolumeBounds> bounds,
SurfaceCandidatesUpdator&& surfaceCandidateUpdator) {
return std::shared_ptr<DetectorVolume>(
new DetectorVolume(gctx, name, transform, std::move(bounds),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ ActsExamples::MockupSectorBuilder::buildChamber(
mCfg.toleranceOverlap;

auto detectorVolumeBounds =
std::make_unique<Acts::CuboidVolumeBounds>(hx, hy, hz);
std::make_shared<Acts::CuboidVolumeBounds>(hx, hy, hz);

Acts::Vector3 chamber_position = {(maxValues.x() + minValues.x()) / 2,
(maxValues.y() + minValues.y()) / 2,
Expand Down Expand Up @@ -197,7 +197,7 @@ ActsExamples::MockupSectorBuilder::buildSector(
std::vector<float> rmins(detVolumesSize);
std::vector<float> rmaxs(detVolumesSize);
std::vector<float> halfZ(detVolumesSize);
std::vector<std::unique_ptr<Acts::CylinderVolumeBounds>>
std::vector<std::shared_ptr<Acts::CylinderVolumeBounds>>
cylinderVolumesBounds(detVolumesSize);

for (int i = 0; i < detVolumesSize; i++) {
Expand All @@ -211,7 +211,7 @@ ActsExamples::MockupSectorBuilder::buildSector(
mCfg.toleranceOverlap;
halfZ[i] = detVol->volumeBounds().values()[2];

cylinderVolumesBounds[i] = std::make_unique<Acts::CylinderVolumeBounds>(
cylinderVolumesBounds[i] = std::make_shared<Acts::CylinderVolumeBounds>(
rmins[i], rmaxs[i], halfZ[i], sectorAngle);
}

Expand Down Expand Up @@ -293,7 +293,7 @@ ActsExamples::MockupSectorBuilder::buildSector(
} // end of cylinder volumes

auto cylinderVolumesBoundsOfMother =
std::make_unique<Acts::CylinderVolumeBounds>(
std::make_shared<Acts::CylinderVolumeBounds>(
rmins.front(), rmaxs.back(),
*std::max_element(halfZ.begin(), halfZ.end()), sectorAngle);

Expand Down
8 changes: 3 additions & 5 deletions Examples/Run/Geant4/TestMockupBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,9 @@ int main() {
mockup_builder.buildChamber(mockup_chamberConfig_outer);

std::vector<std::shared_ptr<Acts::Experimental::DetectorVolume>>
detector_volumes = {};

detector_volumes.push_back(detectorVolume_inner_chamber);
detector_volumes.push_back(detectorVolume_middle_chamber);
detector_volumes.push_back(detectorVolume_outer_chamber);
detector_volumes = {detectorVolume_inner_chamber,
detectorVolume_middle_chamber,
detectorVolume_outer_chamber};

auto detectorVolume_sector = mockup_builder.buildSector(detector_volumes);

Expand Down
30 changes: 26 additions & 4 deletions Plugins/Geant4/include/Acts/Plugins/Geant4/Geant4Converters.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@ struct Geant4AlgebraConverter {
// A potential scalar between Geant4 and ACTS
ActsScalar scale = 1.;

/// @brief Translate a geometry transform: translation only
/// @brief Translate a geometry transform: translation only
///
/// @param g4Trans the translation of the Geant4 object
///
/// @return a Acts transform
Transform3 transform(const G4ThreeVector& g4Trans);

/// @brief Translate a geometry transform
/// @brief Translate a geometry transform
///
/// @param g4Rot the rotation of the Geant4 object
/// @param g4Trans the translation of the Geant4 object
Expand All @@ -49,12 +49,19 @@ struct Geant4AlgebraConverter {
Transform3 transform(const G4RotationMatrix& g4Rot,
const G4ThreeVector& g4Trans);

/// @brief Translate a geometry transform
/// @brief Translate a geometry transform
///
/// @param g4Trf theGeant4 transform object
/// @param g4Trf the Geant4 transform object
///
/// @return a Acts transform
Transform3 transform(const G4Transform3D& g4Trf);

/// @brief Translate a geometry transform from a G4 physical volume
///
/// @param g4PhysVol the Geant4 physical volume
///
/// @return a Acts transform
Transform3 transform(const G4VPhysicalVolume& g4PhysVol);
};

class AnnulusBounds;
Expand Down Expand Up @@ -146,9 +153,13 @@ struct Geant4PhysicalVolumeConverter {
ActsScalar compressed = 0.);
};

class Material;
class HomogeneousSurfaceMaterial;
class HomogeneousVolumeMaterial;

struct Geant4MaterialConverter {
Material material(const G4Material& g4Material, ActsScalar compression = 1);

/// @brief Convert a Geant4 material to a surface material description
///
/// @param g4Material the geant4 material descrition
Expand All @@ -159,4 +170,15 @@ struct Geant4MaterialConverter {
const G4Material& g4Material, ActsScalar original, ActsScalar compressed);
};

class CylinderVolumeBounds;

struct Geant4VolumeConverter {
/// @brief Convert to cylinder bounds
///
/// @param g4Tubs a Geant4 tube shape
///
/// @return an Acts Cylinder bounds object
std::shared_ptr<CylinderVolumeBounds> cylinderBounds(const G4Tubs& g4Tubs);
};

} // namespace Acts
102 changes: 70 additions & 32 deletions Plugins/Geant4/src/Geant4Converters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
#include "Acts/Plugins/Geant4/Geant4Converters.hpp"

#include "Acts/Definitions/Algebra.hpp"
#include "Acts/Geometry/CylinderVolumeBounds.hpp"
#include "Acts/Material/HomogeneousSurfaceMaterial.hpp"
#include "Acts/Material/HomogeneousVolumeMaterial.hpp"
#include "Acts/Material/Material.hpp"
#include "Acts/Material/MaterialSlab.hpp"
#include "Acts/Surfaces/CylinderBounds.hpp"
Expand Down Expand Up @@ -65,33 +67,52 @@ Acts::Transform3 Acts::Geant4AlgebraConverter::transform(
return transform(g4Rot, g4Trans);
}

std::tuple<std::shared_ptr<Acts::CylinderBounds>, Acts::ActsScalar>
Acts::Geant4ShapeConverter::cylinderBounds(const G4Tubs& g4Tubs) {
std::array<Acts::ActsScalar, 6u> tArray = {};
tArray[0u] = static_cast<ActsScalar>(g4Tubs.GetInnerRadius() +
g4Tubs.GetOuterRadius()) *
0.5;
tArray[1u] = static_cast<ActsScalar>(g4Tubs.GetZHalfLength());
tArray[2u] = 0.5 * static_cast<ActsScalar>(g4Tubs.GetDeltaPhiAngle());
tArray[3u] = static_cast<ActsScalar>(g4Tubs.GetStartPhiAngle());
Acts::Transform3 Acts::Geant4AlgebraConverter::transform(
const G4VPhysicalVolume& g4PhysVol) {
// Get Rotation and translation
auto g4Translation = g4PhysVol.GetTranslation();
auto g4Rotation = g4PhysVol.GetRotation();

ActsScalar thickness = (g4Tubs.GetOuterRadius() - g4Tubs.GetInnerRadius());
G4Transform3D g4Transform =
(g4Rotation == nullptr)
? G4Transform3D(CLHEP::HepRotation(), g4Translation)
: G4Transform3D(*g4Rotation, g4Translation);

return transform(g4Transform);
}

std::tuple<std::shared_ptr<Acts::CylinderBounds>, Acts::ActsScalar>
Acts::Geant4ShapeConverter::cylinderBounds(const G4Tubs& g4Tubs) {
using B = Acts::CylinderBounds;

std::array<Acts::ActsScalar, B::eSize> tArray = {};
tArray[B::eR] = static_cast<ActsScalar>(g4Tubs.GetInnerRadius() +
g4Tubs.GetOuterRadius()) *
0.5;
tArray[B::eHalfLengthZ] = static_cast<ActsScalar>(g4Tubs.GetZHalfLength());
tArray[B::eHalfPhiSector] =
0.5 * static_cast<ActsScalar>(g4Tubs.GetDeltaPhiAngle());
tArray[B::eAveragePhi] = static_cast<ActsScalar>(g4Tubs.GetStartPhiAngle());

ActsScalar thickness = g4Tubs.GetOuterRadius() - g4Tubs.GetInnerRadius();
auto cBounds = std::make_shared<CylinderBounds>(tArray);
return std::tie(cBounds, thickness);
return std::make_tuple(std::move(cBounds), thickness);
}

std::tuple<std::shared_ptr<Acts::RadialBounds>, Acts::ActsScalar>
Acts::Geant4ShapeConverter::radialBounds(const G4Tubs& g4Tubs) {
std::array<ActsScalar, 4u> tArray = {};
tArray[0u] = static_cast<ActsScalar>(g4Tubs.GetInnerRadius());
tArray[1u] = static_cast<ActsScalar>(g4Tubs.GetOuterRadius());
tArray[2u] = 0.5 * static_cast<ActsScalar>(g4Tubs.GetDeltaPhiAngle());
tArray[3u] = static_cast<ActsScalar>(g4Tubs.GetStartPhiAngle());
using B = Acts::RadialBounds;

std::array<ActsScalar, B::eSize> tArray = {};
tArray[B::eMinR] = static_cast<ActsScalar>(g4Tubs.GetInnerRadius());
tArray[B::eMaxR] = static_cast<ActsScalar>(g4Tubs.GetOuterRadius());
tArray[B::eHalfPhiSector] =
0.5 * static_cast<ActsScalar>(g4Tubs.GetDeltaPhiAngle());
tArray[B::eAveragePhi] = static_cast<ActsScalar>(g4Tubs.GetStartPhiAngle());

ActsScalar thickness = g4Tubs.GetZHalfLength() * 2;
auto rBounds = std::make_shared<RadialBounds>(tArray);
return std::tie(rBounds, thickness);
return std::make_tuple(std::move(rBounds), thickness);
}

std::shared_ptr<Acts::LineBounds> Acts::Geant4ShapeConverter::lineBounds(
Expand Down Expand Up @@ -131,7 +152,7 @@ Acts::Geant4ShapeConverter::rectangleBounds(const G4Box& g4Box) {
}
auto rBounds = std::make_shared<RectangleBounds>(hG4XYZ[std::abs(rAxes[0u])],
hG4XYZ[std::abs(rAxes[1u])]);
return std::tie(rBounds, rAxes, thickness);
return std::make_tuple(std::move(rBounds), rAxes, thickness);
}

std::tuple<std::shared_ptr<Acts::TrapezoidBounds>, std::array<int, 2u>,
Expand Down Expand Up @@ -186,7 +207,7 @@ Acts::Geant4ShapeConverter::trapezoidBounds(const G4Trd& g4Trd) {

auto tBounds = std::make_shared<TrapezoidBounds>(
halfLengthXminY, halfLengthXmaxY, halfLengthY);
return std::tie(tBounds, rAxes, thickness);
return std::make_tuple(std::move(tBounds), rAxes, thickness);
}

std::tuple<std::shared_ptr<Acts::PlanarBounds>, std::array<int, 2u>,
Expand All @@ -195,19 +216,19 @@ Acts::Geant4ShapeConverter::planarBounds(const G4VSolid& g4Solid) {
const G4Box* box = dynamic_cast<const G4Box*>(&g4Solid);
if (box != nullptr) {
auto [rBounds, axes, thickness] = rectangleBounds(*box);
return std::tie(rBounds, axes, thickness);
return std::make_tuple(std::move(rBounds), axes, thickness);
}

const G4Trd* trd = dynamic_cast<const G4Trd*>(&g4Solid);
if (trd != nullptr) {
auto [tBounds, axes, thickness] = trapezoidBounds(*trd);
return std::tie(tBounds, axes, thickness);
return std::make_tuple(std::move(tBounds), axes, thickness);
}

std::shared_ptr<Acts::PlanarBounds> pBounds = nullptr;
std::array<int, 2u> rAxes = {};
ActsScalar rThickness = 0.;
return std::tie(pBounds, rAxes, rThickness);
return std::make_tuple(std::move(pBounds), rAxes, rThickness);
}

namespace {
Expand Down Expand Up @@ -246,7 +267,7 @@ std::shared_ptr<Acts::Surface> Acts::Geant4PhysicalVolumeConverter::surface(
}
auto surfaceMaterial = Geant4MaterialConverter{}.surfaceMaterial(
*g4Material, moriginal, mcompressed);
sf.assignSurfaceMaterial(surfaceMaterial);
sf.assignSurfaceMaterial(std::move(surfaceMaterial));
}
};

Expand Down Expand Up @@ -321,12 +342,8 @@ std::shared_ptr<Acts::Surface> Acts::Geant4PhysicalVolumeConverter::surface(
return nullptr;
}

std::shared_ptr<Acts::HomogeneousSurfaceMaterial>
Acts::Geant4MaterialConverter::surfaceMaterial(const G4Material& g4Material,
ActsScalar original,
ActsScalar compressed) {
ActsScalar compression = original / compressed;

Acts::Material Acts::Geant4MaterialConverter::material(
const G4Material& g4Material, ActsScalar compression) {
auto X0 = g4Material.GetRadlen();
auto L0 = g4Material.GetNuclearInterLength();
auto Rho = g4Material.GetDensity();
Expand All @@ -348,9 +365,30 @@ Acts::Geant4MaterialConverter::surfaceMaterial(const G4Material& g4Material,
}
}

Material mat = Material::fromMassDensity(X0 / compression, L0 / compression,
Ar, Z, compression * Rho);
return Material::fromMassDensity(X0 / compression, L0 / compression, Ar, Z,
compression * Rho);
}

std::shared_ptr<Acts::HomogeneousSurfaceMaterial>
Acts::Geant4MaterialConverter::surfaceMaterial(const G4Material& g4Material,
ActsScalar original,
ActsScalar compressed) {
ActsScalar compression = original / compressed;
return std::make_shared<HomogeneousSurfaceMaterial>(
MaterialSlab(mat, compressed));
MaterialSlab(material(g4Material, compression), compressed));
}

std::shared_ptr<Acts::CylinderVolumeBounds>
Acts::Geant4VolumeConverter::cylinderBounds(const G4Tubs& g4Tubs) {
using C = Acts::CylinderVolumeBounds;

std::array<Acts::ActsScalar, C::eSize> tArray = {};
tArray[C::eMinR] = static_cast<ActsScalar>(g4Tubs.GetInnerRadius());
tArray[C::eMaxR] = static_cast<ActsScalar>(g4Tubs.GetOuterRadius());
tArray[C::eHalfLengthZ] = static_cast<ActsScalar>(g4Tubs.GetZHalfLength());
tArray[C::eHalfPhiSector] =
0.5 * static_cast<ActsScalar>(g4Tubs.GetDeltaPhiAngle());
tArray[C::eAveragePhi] = static_cast<ActsScalar>(g4Tubs.GetStartPhiAngle());

return std::make_shared<CylinderVolumeBounds>(tArray);
}

0 comments on commit 9a19dbc

Please sign in to comment.