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: Geometry ID Generator aka ODD light part3 #2462

Merged
merged 7 commits into from
Sep 20, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
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
5 changes: 5 additions & 0 deletions Core/include/Acts/Detector/CylindricalContainerBuilder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ namespace Acts {
namespace Experimental {

class IRootVolumeFinderBuilder;
class IGeometryIdGenerator;

/// @brief A dedicated container builder for cylindrical detector containers
///
Expand All @@ -45,6 +46,10 @@ class CylindricalContainerBuilder : public IDetectorComponentBuilder {
std::vector<BinningValue> binning = {};
/// The root volume finder
std::shared_ptr<IRootVolumeFinderBuilder> rootVolumeFinderBuilder = nullptr;
/// The geometry id generator
std::shared_ptr<const IGeometryIdGenerator> geoIdGenerator = nullptr;
/// An eventual reverse geometry id generation
bool geoIdReverseGen = false;
/// Auxiliary information, mainly for screen output
std::string auxiliary = "";
};
Expand Down
13 changes: 13 additions & 0 deletions Core/include/Acts/Detector/Detector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include "Acts/Definitions/Common.hpp"
#include "Acts/Detector/DetectorVolume.hpp"
#include "Acts/Geometry/GeometryContext.hpp"
#include "Acts/Geometry/GeometryHierarchyMap.hpp"
#include "Acts/Geometry/GeometryIdentifier.hpp"
#include "Acts/Navigation/NavigationDelegates.hpp"
#include "Acts/Utilities/Delegate.hpp"

Expand All @@ -23,6 +25,9 @@
#include <vector>

namespace Acts {

class Surface;

namespace Experimental {
struct NavigationState;

Expand Down Expand Up @@ -90,6 +95,11 @@ class Detector : public std::enable_shared_from_this<Detector> {
/// @return a vector to const DetectorVolume raw pointers
const std::vector<const DetectorVolume*>& volumes() const;

/// Const access to the hierarchy map of all sensitive surfaces
///
/// @return the map which can be queried with GeometryID for ranges
const GeometryHierarchyMap<const Surface*>& sensitiveHierarchyMap() const;

/// Update the current volume of a given navigation state
///
/// @param gctx is the Geometry context of the call
Expand Down Expand Up @@ -142,6 +152,9 @@ class Detector : public std::enable_shared_from_this<Detector> {

/// Name/index map to find volumes by name and detect duplicates
std::unordered_map<std::string, size_t> m_volumeNameIndex;

/// Geometry Id hierarchy map of all sensitive surfaces
GeometryHierarchyMap<const Surface*> m_sensitiveHierarchyMap;
};

} // namespace Experimental
Expand Down
4 changes: 4 additions & 0 deletions Core/include/Acts/Detector/DetectorBuilder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
namespace Acts {
namespace Experimental {

class IGeometryIdGenerator;

/// @brief Standard generic Detector builder that calls
/// the top level component builder and transfers the
/// result into a detector object
Expand All @@ -33,6 +35,8 @@ class DetectorBuilder final : public IDetectorBuilder {
std::string name = "unnamed";
/// An external builder
std::shared_ptr<const IDetectorComponentBuilder> builder = nullptr;
/// A geometry id generator
std::shared_ptr<const IGeometryIdGenerator> geoIdGenerator = nullptr;
/// Auxiliary information
std::string auxiliary = "";
};
Expand Down
6 changes: 6 additions & 0 deletions Core/include/Acts/Detector/DetectorVolume.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,12 @@ class DetectorVolume : public std::enable_shared_from_this<DetectorVolume> {
/// @return the geometry identifier
const GeometryIdentifier& geometryId() const;

/// Set the geometry identifier
/// @note no checking is done, it will overwrite any existing id
///
/// @param geoID is the geometry Id that is set to the object
void assignGeometryId(const GeometryIdentifier& geoID);

/// Assign Detector to this volume (for back navigation issues)
/// @param detector the parenting detector class
void assignDetector(const Detector& detector);
Expand Down
3 changes: 3 additions & 0 deletions Core/include/Acts/Detector/DetectorVolumeBuilder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ namespace Acts {
namespace Experimental {
class IExternalStructureBuilder;
class IInternalStructureBuilder;
class IGeometryIdGenerator;

/// @brief A generic detector volume builder that uses
/// an external builder for shape and portals and an internal
Expand All @@ -41,6 +42,8 @@ class DetectorVolumeBuilder : public IDetectorComponentBuilder {
std::shared_ptr<const IExternalStructureBuilder> externalsBuilder = nullptr;
/// An internal builder
std::shared_ptr<const IInternalStructureBuilder> internalsBuilder = nullptr;
/// The geometry id generator
std::shared_ptr<const IGeometryIdGenerator> geoIdGenerator = nullptr;
/// Add eventual internal volume to root
bool addInternalsToRoot = false;
/// Auxiliary information
Expand Down
125 changes: 125 additions & 0 deletions Core/include/Acts/Detector/GeometryIdGenerator.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
// This file is part of the Acts project.
//
// Copyright (C) 2023 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/Detector/interface/IGeometryIdGenerator.hpp"
#include "Acts/Geometry/GeometryIdentifier.hpp"
#include "Acts/Utilities/Logger.hpp"

#include <any>

namespace Acts {

class Surface;

namespace Experimental {

class Portal;
class DetectorVolume;

/// @brief This is the default implementation of the geometry id generator
///
/// It is a simple counter based generator that assigns ids to the geometry
/// and increments the counter for each object type.
///
/// Sub counters, i.e. for the sensitive surfaces, are reset after the volume
/// call, such that a new volume or layer volume would start from counter 0
/// again.
///
/// If the generator is configured to override existing ids, it will do so
/// and not respect previously assigned ids.
///
/// If the generator is configured in container mode, it will increase the
/// layer id for each layer volume with confined surfaces.
///
class GeometryIdGenerator final : public IGeometryIdGenerator {
public:
/// @brief Nested config struct
struct Config {
/// Container mode
bool containerMode = false;
/// Container id (if container mode), will not be incremented
unsigned int containerId = 0u;
/// Resetting mode
bool resetSubCounters = true;
/// Force override existing ids
bool overrideExistingIds = false;
};

/// @brief Nested cache struct
struct Cache {
/// Cache count of the volume, for non-container mode
unsigned int volumeCount = 0u;
/// Cache count of the layer volume, for container mode
unsigned int layerCount = 0u;
/// Cache count of the portal surfaces
unsigned int portalCount = 0u;
/// Cache count of passive surfaces
unsigned int passiveCount = 0u;
/// Cache count of sensitive surfaces
unsigned int sensitiveCount = 0u;
};

/// @brief Constructor with config
///
/// @param cfg is the geometry configuration object
/// @param mlogger is the logging instance
GeometryIdGenerator(const Config& cfg,
std::unique_ptr<const Logger> mlogger = getDefaultLogger(
"GeometryIdGenerator", Logging::INFO))
: m_cfg(cfg), m_logger(std::move(mlogger)) {}

~GeometryIdGenerator() override = default;

/// @brief Interface method to generata a geometry id cache
/// @return a geometry id cache decorated in a std::any object
IGeometryIdGenerator::GeoIdCache generateCache() const final;

/// @brief Method for assigning a geometry id to a detector volume
///
/// @param cache is the cache object for e.g. object counting
/// @param dVolume the detector volume to assign the geometry id to
void assignGeometryId(IGeometryIdGenerator::GeoIdCache& cache,
DetectorVolume& dVolume) const final;

/// @brief Method for assigning a geometry id to a portal
///
/// @param cache is the cache object for e.g. object counting
/// @param portal the portal to assign the geometry id to
void assignGeometryId(IGeometryIdGenerator::GeoIdCache& cache,
Portal& portal) const final;

/// @brief Method for assigning a geometry id to a surface
///
/// @param cache is the cache object for e.g. object counting
/// @param surface the surface to assign the geometry id to
void assignGeometryId(IGeometryIdGenerator::GeoIdCache& cache,
Surface& surface) const final;

private:
/// @brief Helper method to get the volume id from the cache
///
/// @param cache the provided cache
/// @param incrementLayer if true, the layer counter is incremented
///
/// @return a valid geometry identifier
GeometryIdentifier volumeId(Cache& cache, bool incrementLayer = true) const;

/// Configuration object
Config m_cfg;

/// Private access method to the logger
const Logger& logger() const { return *m_logger; }

/// logging instance
std::unique_ptr<const Logger> m_logger;
};

} // namespace Experimental
} // namespace Acts
59 changes: 59 additions & 0 deletions Core/include/Acts/Detector/interface/IGeometryIdGenerator.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// This file is part of the Acts project.
//
// Copyright (C) 2023 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 <any>

namespace Acts {

class Surface;

namespace Experimental {

class Portal;
class DetectorVolume;

/// @brief This is the interface for generating geometry ids and assign them
/// to detector volumes, portals and surfaces
///
class IGeometryIdGenerator {
public:
using GeoIdCache = std::any;

virtual ~IGeometryIdGenerator() = default;

/// @brief Virtual interface method to generata a geometry id cache
/// @return a geometry id cache decorated in a std::any object
virtual GeoIdCache generateCache() const = 0;

/// The virtual interface definition for assigning a geometry id to
/// a detector volume
///
/// @param cache is the cache object for e.g. object counting
/// @param dVolume the detector volume to assign the geometry id to
virtual void assignGeometryId(GeoIdCache& cache,
DetectorVolume& dVolume) const = 0;

/// The virtual interface definition for assigning a geometry id to
/// a portal
///
/// @param cache is the cache object for e.g. object counting
/// @param portal the portal to assign the geometry id to
virtual void assignGeometryId(GeoIdCache& cache, Portal& portal) const = 0;

/// @brief The virtual interface definition for assigning a geometry id to
/// a surface
///
/// @param cache is the cache object for e.g. object counting
/// @param surface the surface to assign the geometry id to
virtual void assignGeometryId(GeoIdCache& cache, Surface& surface) const = 0;
};

} // namespace Experimental
} // namespace Acts
7 changes: 7 additions & 0 deletions Core/include/Acts/Geometry/GeometryIdentifier.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ class GeometryIdentifier {
constexpr Value layer() const { return getBits(kLayerMask); }
/// Return the approach identifier.
constexpr Value approach() const { return getBits(kApproachMask); }
/// Return the approach identifier.
constexpr Value passive() const { return getBits(kApproachMask); }
/// Return the sensitive identifier.
constexpr Value sensitive() const { return getBits(kSensitiveMask); }
/// Return the extra identifier
Expand All @@ -76,6 +78,10 @@ class GeometryIdentifier {
constexpr GeometryIdentifier& setApproach(Value approach) {
return setBits(kApproachMask, approach);
}
/// Set the approach identifier - shared with Passive
constexpr GeometryIdentifier& setPassive(Value approach) {
return setBits(kApproachMask, approach);
}
/// Set the sensitive identifier.
constexpr GeometryIdentifier& setSensitive(Value sensitive) {
return setBits(kSensitiveMask, sensitive);
Expand All @@ -95,6 +101,7 @@ class GeometryIdentifier {
static constexpr Value kLayerMask = 0x0000fff000000000;
/// (2^8)-1 = 255 approach surfaces
static constexpr Value kApproachMask = 0x0000000ff0000000;
static constexpr Value kPassiveMask = kApproachMask;
/// (2^20)-1 = 1048575 sensitive surfaces
static constexpr Value kSensitiveMask = 0x000000000fffff00;
/// (2^8)-1 = 255 extra values
Expand Down
1 change: 1 addition & 0 deletions Core/src/Detector/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ target_sources(
Portal.cpp
PortalGenerators.cpp
ProtoDetector.cpp
GeometryIdGenerator.cpp
VolumeStructureBuilder.cpp
MultiWireStructureBuilder.cpp

Expand Down
16 changes: 16 additions & 0 deletions Core/src/Detector/CylindricalContainerBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include "Acts/Detector/DetectorComponents.hpp"
#include "Acts/Detector/detail/CylindricalDetectorHelper.hpp"
#include "Acts/Detector/interface/IGeometryIdGenerator.hpp"
#include "Acts/Detector/interface/IRootVolumeFinderBuilder.hpp"
#include "Acts/Navigation/DetectorVolumeFinders.hpp"

Expand Down Expand Up @@ -166,6 +167,21 @@ Acts::Experimental::CylindricalContainerBuilder::construct(
m_cfg.rootVolumeFinderBuilder->construct(gctx, rootVolumes)}};
}

// Geometry Id generation
if (m_cfg.geoIdGenerator != nullptr) {
ACTS_DEBUG("Assigning geometry ids to the detector");
auto cache = m_cfg.geoIdGenerator->generateCache();
if (m_cfg.geoIdReverseGen) {
std::for_each(rootVolumes.rbegin(), rootVolumes.rend(), [&](auto& v) {
m_cfg.geoIdGenerator->assignGeometryId(cache, *v);
});
} else {
std::for_each(rootVolumes.begin(), rootVolumes.end(), [&](auto& v) {
m_cfg.geoIdGenerator->assignGeometryId(cache, *v);
});
}
}

// Return the container
return Acts::Experimental::DetectorComponent{
{}, rContainer, RootDetectorVolumes{rootVolumes, tryRootVolumes()}};
Expand Down
Loading
Loading