Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: GeoModel plugin changes for ITk building. #3519

Closed
Show file tree
Hide file tree
Changes from 47 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
025527c
it works!
Jul 26, 2024
7dbcc0d
clang-format
Jul 26, 2024
d5efd30
remove some unused stuff
Jul 26, 2024
7bdebc3
update outer pixel
Jul 26, 2024
aaea283
black format
Jul 26, 2024
74e8c7b
remove dead code
Jul 26, 2024
eb25f13
Merge branch 'main' into feature/gen1-itk
Jul 29, 2024
e1b72b6
remove build script / undo unrelated stuff
Jul 29, 2024
d0f914b
remove remaining leftovers
Jul 29, 2024
7e962ff
some changes
Jul 30, 2024
3738431
avoid segfaults in bin adjustments
Aug 2, 2024
83ed5a1
change to dynamic cast only
Aug 2, 2024
1f333f9
format
Aug 2, 2024
18da1de
some python updates
Aug 2, 2024
7b31c7a
refactor bin adjustement again
Aug 2, 2024
aa2fdd9
Merge branch 'main' into feature/gen1-itk-material
Aug 15, 2024
d187a9e
add vertex writing of annulus bounds to CsvTrackingGeometryWriter
Aug 15, 2024
6081497
some hacky changes to get more data
Aug 16, 2024
6acb330
Make some ITk specific stuff work
Aug 19, 2024
250db14
smaller cleanups
Aug 20, 2024
a28cb57
a bit more cleanup
Aug 20, 2024
434d68c
Merge branch 'main' into feature/gen1-itk-material
Aug 20, 2024
7aa89a6
revert changes not related to geomodel
Aug 20, 2024
0e0b7cf
improve doc
Aug 20, 2024
cd509e6
Merge branch 'main' into feature/gen1-itk-geomodel-changes
Aug 21, 2024
478aa87
some renaming, add test
Aug 21, 2024
769f910
update
Aug 21, 2024
615a3e3
fix cmake
Aug 21, 2024
2cadcbb
Merge branch 'main' into feature/gen1-itk-geomodel-changes
Aug 27, 2024
7495699
review
Aug 27, 2024
233486c
update
Aug 27, 2024
a4e32fa
fix
Aug 27, 2024
f336c8f
fix
Aug 27, 2024
ad8b843
fix unittest
Aug 27, 2024
dbdf19c
apply review
Aug 28, 2024
cdcac20
Apply suggestions from code review
benjaminhuth Aug 28, 2024
422840a
revert thing
Aug 28, 2024
93a803a
fix
Aug 28, 2024
038e27d
update
Aug 29, 2024
9614e6b
spelling
Aug 29, 2024
6728429
add test
Aug 29, 2024
5e6e1cb
fix test
Aug 29, 2024
592399a
update
Aug 29, 2024
ffe3ada
Merge branch 'main' into feature/gen1-itk-geomodel-changes
AJPfleger Aug 29, 2024
a64a2a5
Merge branch 'main' into feature/gen1-itk-geomodel-changes
AJPfleger Aug 29, 2024
e16a725
make clang-tidy happy
Aug 29, 2024
1764173
Merge branch 'main' into feature/gen1-itk-geomodel-changes
kodiakhq[bot] Aug 30, 2024
60b5903
change module splitter to be unified with ITk module splitter
Sep 2, 2024
159d4a5
fix
Sep 2, 2024
f44faa3
fix
Sep 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion Examples/Python/src/GeoModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
#include "Acts/Plugins/GeoModel/GeoModelBlueprintCreater.hpp"
#include "Acts/Plugins/GeoModel/GeoModelConverters.hpp"
#include "Acts/Plugins/GeoModel/GeoModelDetectorElement.hpp"
#include "Acts/Plugins/GeoModel/GeoModelDetectorElementITk.hpp"
#include "Acts/Plugins/GeoModel/GeoModelDetectorObjectFactory.hpp"
#include "Acts/Plugins/GeoModel/GeoModelModuleSplitter.hpp"
#include "Acts/Plugins/GeoModel/GeoModelReader.hpp"
#include "Acts/Plugins/GeoModel/GeoModelTree.hpp"
#include "Acts/Plugins/GeoModel/IGeoShapeConverter.hpp"
Expand Down Expand Up @@ -46,7 +48,10 @@ void addGeoModel(Context& ctx) {

py::class_<Acts::GeoModelDetectorElement,
std::shared_ptr<Acts::GeoModelDetectorElement>>(
gm, "GeoModelDetectorElement");
gm, "GeoModelDetectorElement")
.def("logVolName", &Acts::GeoModelDetectorElement::logVolName)
.def("databaseEntryName",
&Acts::GeoModelDetectorElement::databaseEntryName);

// Shape converters
{
Expand Down Expand Up @@ -184,5 +189,17 @@ void addGeoModel(Context& ctx) {
.def_readwrite("table",
&Acts::GeoModelBlueprintCreater::Options::table);
}

py::class_<Acts::GeoModelModuleSplitter>(gm, "GeoModelModuleSplitter")
.def(py::init<std::map<std::string, std::vector<double>>, double,
Acts::Logging::Level>(),
"self"_a, "designs"_a, "tolerance", "level"_a)
.def("split", &Acts::GeoModelModuleSplitter::split, "detElement"_a,
"gctx"_a);

py::class_<Acts::GeoModelDetectorElementITk,
std::shared_ptr<Acts::GeoModelDetectorElementITk>>(
gm, "GeoModelDetectorElementITk");
gm.def("convertToItk", &GeoModelDetectorElementITk::convertFromGeomodel);
}
} // namespace Acts::Python
2 changes: 2 additions & 0 deletions Plugins/GeoModel/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ add_library(
src/detail/GeoModelBinningHelper.cpp
src/detail/GeoModelExtentHelper.cpp
src/detail/GeoUnionDoubleTrdConverter.cpp
src/GeoModelModuleSplitter.cpp
src/GeoModelDetectorElementITk.cpp
)
target_include_directories(
ActsPluginGeoModel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,28 @@ class GeoModelDetectorElement : public DetectorElementBase {
/// @return to the Geant4 physical volume
PVConstLink physicalVolume() const;

private:
/// Get the name of the logical volume
const std::string& logVolName() const;

/// Get the string identifier of the corresponding database entry
/// Note: This is not by defnitition a unique identifier, there can be
/// several detector elements created from a single database entry.
const std::string& databaseEntryName() const { return m_entryName; };

/// Set the corresponding database entry string
void setDatabaseEntryName(const std::string& n) { m_entryName = n; };

protected:
/// Attach a surface
///
/// @param surface The surface to attach
void attachSurface(std::shared_ptr<Surface> surface) {
m_surface = std::move(surface);
}

private:
std::string m_entryName;

/// The GeoModel full physical volume
PVConstLink m_geoPhysVol{nullptr};
/// The surface
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// This file is part of the Acts project.
//
// Copyright (C) 2024 CERN for the benefit of the Acts project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#pragma once

#include "Acts/Plugins/GeoModel/GeoModelDetectorElement.hpp"
#include "Acts/Utilities/MultiIndex.hpp"

namespace Acts {

class ITkIdentifier {
Acts::MultiIndex<std::size_t, 1, 2, 20, 20, 20, 1> m_identifier{};

public:
ITkIdentifier(int hardware, int barrelEndcap, int layerWheel, int etaModule,
int phiModule, int side);

/// Access the hardware specifier (pixel=0, strip=1)
int hardware() const;

/// Access the barrel-endcap specifier (-2,0,2)
int barrelEndcap() const;

/// Access the layer specifier
int layerWheel() const;

/// Access the phi module specifier
int phiModule() const;

/// Access the eta module specifier
int etaModule() const;

/// Access the side (for double sided strip modules)
int side() const;

/// A unique identifier that represents the combination of specifiers
std::size_t value() const;
};

/// Specialization of the GeoModelDetectorElement for the ITk. This allows
/// mapping of Acts::GeometryIdentifiers to ITk modules in a straight-forward
/// way.
class GeoModelDetectorElementITk : public GeoModelDetectorElement {
public:
GeoModelDetectorElementITk(const PVConstLink& geoPhysVol,
std::shared_ptr<Surface> surface,
const Transform3& sfTransform,
ActsScalar thickness, int hardware,
int barrelEndcap, int layerWheel, int etaModule,
int phiModule, int side)
: GeoModelDetectorElement(geoPhysVol, std::move(surface), sfTransform,
thickness),
m_identifier(hardware, barrelEndcap, layerWheel, etaModule, phiModule,
side) {}

ITkIdentifier identifier() const { return m_identifier; }

/// Convert a GeoModelDetectorElement to a GeoModelDetectorElementITk
/// A new surface is constructed.
/// @todo Remove redundancy in signature once plugin is refactored
static std::tuple<std::shared_ptr<GeoModelDetectorElementITk>,
std::shared_ptr<Surface>>
convertFromGeomodel(std::shared_ptr<GeoModelDetectorElement> detEl,
std::shared_ptr<Surface> srf, const GeometryContext& gctx,
int hardware, int barrelEndcap, int layerWheel,
int etaModule, int phiModule, int side);

private:
ITkIdentifier m_identifier;
};

} // namespace Acts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// This file is part of the Acts project.
//
// Copyright (C) 2024 CERN for the benefit of the Acts project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#pragma once

#include "Acts/Plugins/GeoModel/GeoModelDetectorElement.hpp"
#include "Acts/Utilities/Logger.hpp"

#include <map>
#include <string>
#include <vector>

namespace Acts {

/// This class allows to split modules with annulus shape along into several
/// parts with the help of a list of radii. This is used for building
/// an ITk geometry.
/// The splitting works based on a provided list of radii [r0, r1, ..., rN]:
/// An annulus bound with radial constraint (rA, rB) is split in N-1 bounds
/// with radii (r0,r1), (r1,r2), ...
/// A pattern is only accepted, if rA ~ r0 and rB ~ r1 up to a configurable
/// tolerance.
class GeoModelModuleSplitter {
public:
/// Construct the module splitter
/// @param splitPatterns A map of named split patterns
benjaminhuth marked this conversation as resolved.
Show resolved Hide resolved
/// @param tolerance The tolerance applied when matching the split
/// patterns to the modules
/// @param level The level of the internal logger
/// @throws std::runtime_error if the surface does not has annulus
/// bounds or no pattern matches
GeoModelModuleSplitter(
const std::map<std::string, std::vector<double>> &splitPatterns,
double tolerance = 1.e-3,
Acts::Logging::Level level = Acts::Logging::INFO)
: m_splitPatterns(splitPatterns),
m_tolerance(tolerance),
m_logger(getDefaultLogger("GeoModelModuleSplitter", level)) {}

/// Perform the split for a detector element
/// @param detElement The detector element to split
/// @param gctx The geometry context
std::vector<std::shared_ptr<GeoModelDetectorElement>> split(
std::shared_ptr<GeoModelDetectorElement> detElement,
const GeometryContext &gctx) const;

private:
std::map<std::string, std::vector<double>> m_splitPatterns;
double m_tolerance;
std::unique_ptr<const Acts::Logger> m_logger;
};

} // namespace Acts
6 changes: 6 additions & 0 deletions Plugins/GeoModel/src/GeoModelDetectorElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

#include <utility>

#include <GeoModelKernel/GeoFullPhysVol.h>

Acts::GeoModelDetectorElement::GeoModelDetectorElement(
PVConstLink geoPhysVol, std::shared_ptr<Surface> surface,
const Transform3& sfTransform, ActsScalar thickness)
Expand Down Expand Up @@ -40,3 +42,7 @@ Acts::ActsScalar Acts::GeoModelDetectorElement::thickness() const {
PVConstLink Acts::GeoModelDetectorElement::physicalVolume() const {
return m_geoPhysVol;
}

const std::string& Acts::GeoModelDetectorElement::logVolName() const {
return m_geoPhysVol->getLogVol()->getName();
}
108 changes: 108 additions & 0 deletions Plugins/GeoModel/src/GeoModelDetectorElementITk.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// This file is part of the Acts project.
//
// Copyright (C) 2024 CERN for the benefit of the Acts project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "Acts/Plugins/GeoModel/GeoModelDetectorElementITk.hpp"

#include "Acts/Surfaces/AnnulusBounds.hpp"
#include "Acts/Surfaces/DiscSurface.hpp"
#include "Acts/Surfaces/PlaneSurface.hpp"
#include "Acts/Surfaces/RectangleBounds.hpp"

#include <ranges>

namespace Acts {

// Mapping between the barrel-endcap identifier and its unsigned representation
constexpr static std::array<std::pair<unsigned, int>, 3> s_barrelEndcapMap{
{{0, 0}, {1, 2}, {2, -2}}};

Acts::ITkIdentifier::ITkIdentifier(int hardware, int barrelEndcap,
int layerWheel, int etaModule, int phiModule,
int side) {
m_identifier.set(0, hardware);

auto found = std::ranges::find(s_barrelEndcapMap, barrelEndcap,
&std::pair<unsigned, int>::second);
if (found == s_barrelEndcapMap.end()) {
throw std::invalid_argument("Invalid barrel-endcap specifier");
}
m_identifier.set(1, found->first);
m_identifier.set(2, layerWheel);
m_identifier.set(3, etaModule);
m_identifier.set(4, phiModule);
m_identifier.set(5, side);
}

int Acts::ITkIdentifier::hardware() const {
return m_identifier.level(0);
}

int Acts::ITkIdentifier::barrelEndcap() const {
auto found = std::ranges::find(s_barrelEndcapMap, m_identifier.level(1),
&std::pair<unsigned, int>::first);
if (found == s_barrelEndcapMap.end()) {
throw std::invalid_argument("Invalid barrel-endcap specifier");
}
return found->second;
}

int Acts::ITkIdentifier::layerWheel() const {
return m_identifier.level(2);
}

int Acts::ITkIdentifier::phiModule() const {
return m_identifier.level(3);
}

int Acts::ITkIdentifier::etaModule() const {
return m_identifier.level(4);
}

int Acts::ITkIdentifier::side() const {
return m_identifier.level(5);
}

std::size_t Acts::ITkIdentifier::value() const {
return m_identifier.value();
}

std::tuple<std::shared_ptr<Acts::GeoModelDetectorElementITk>,
std::shared_ptr<Acts::Surface>>
Acts::GeoModelDetectorElementITk::convertFromGeomodel(
paulgessinger marked this conversation as resolved.
Show resolved Hide resolved
std::shared_ptr<GeoModelDetectorElement> detEl,
std::shared_ptr<Surface> srf, const GeometryContext& gctx, int hardware,
int barrelEndcap, int layerWheel, int etaModule, int phiModule, int side) {
auto helper = [&]<typename surface_t, typename bounds_t>() {
auto bounds = std::make_shared<bounds_t>(
dynamic_cast<const bounds_t&>(srf->bounds()));

auto itkEl = std::make_shared<GeoModelDetectorElementITk>(
detEl->physicalVolume(), nullptr, detEl->transform(gctx),
detEl->thickness(), hardware, barrelEndcap, layerWheel, etaModule,
phiModule, side);
benjaminhuth marked this conversation as resolved.
Show resolved Hide resolved
auto surface = Surface::makeShared<surface_t>(bounds, *itkEl.get());

itkEl->attachSurface(surface);
itkEl->setDatabaseEntryName(detEl->databaseEntryName());
benjaminhuth marked this conversation as resolved.
Show resolved Hide resolved
benjaminhuth marked this conversation as resolved.
Show resolved Hide resolved
return std::pair{itkEl, surface};
};

if (srf->type() == Acts::Surface::Plane &&
srf->bounds().type() == Acts::SurfaceBounds::eRectangle) {
return helper.operator()<Acts::PlaneSurface, Acts::RectangleBounds>();
}
if (srf->type() == Acts::Surface::Disc &&
srf->bounds().type() == Acts::SurfaceBounds::eAnnulus) {
return helper.operator()<Acts::DiscSurface, Acts::AnnulusBounds>();
}

throw std::runtime_error(
"Only Plane+Rectangle and Disc+Annulus are converted for the ITk");
}

} // namespace Acts
10 changes: 10 additions & 0 deletions Plugins/GeoModel/src/GeoModelDetectorObjectFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,9 @@ void Acts::GeoModelDetectorObjectFactory::convertFpv(
fpv->getAbsoluteTransform() * surface.transform;
convertSensitive(surface.volume, transform, sensitives);
}
for (auto &[detEl, _] : sensitives) {
detEl->setDatabaseEntryName(name);
}
cache.sensitiveSurfaces.insert(cache.sensitiveSurfaces.end(),
sensitives.begin(), sensitives.end());
if (convertBox(name)) {
Expand All @@ -179,9 +182,16 @@ void Acts::GeoModelDetectorObjectFactory::convertFpv(
cache.boundingBoxes.push_back(box);
}
} else {
const auto prevSize = cache.sensitiveSurfaces.size();

// convert fpvs to surfaces
const Transform3 &transform = fpv->getAbsoluteTransform();
convertSensitive(fpv, transform, cache.sensitiveSurfaces);

for (auto i = prevSize; i < cache.sensitiveSurfaces.size(); ++i) {
auto &[detEl, _] = cache.sensitiveSurfaces[i];
detEl->setDatabaseEntryName(name);
}
}
}
// lambda to determine if object fits query
Expand Down
Loading
Loading