Skip to content

Commit

Permalink
feat: adding portal, detector volume & detector (#1645)
Browse files Browse the repository at this point in the history
This PR adds the new Portal, DetectorVolume and Detector geometry which is meant to eventually replace the Layer, TrackingVolume, TrackingGeometry infrastructure.

The new classes are currently put under the Experimental namespace.

Only the new classes, the necessary definitions and unit tests are added with this PR, which will be followed up by the visualisation, the detector building and the navigation code.

A description of the concepts and classes is added to the
docs/experimental_geometry.md to this PR.
  • Loading branch information
asalzburger authored Nov 22, 2022
1 parent 4e2c890 commit 3898a7f
Show file tree
Hide file tree
Showing 38 changed files with 3,750 additions and 3 deletions.
43 changes: 42 additions & 1 deletion Core/include/Acts/Definitions/Common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,53 @@ static constexpr ActsScalar s_curvilinearProjTolerance = 0.999995;
/// respect to a given momentum or direction
enum class NavigationDirection : int { Backward = -1, Forward = 1 };

inline constexpr NavigationDirection directionFromStepSize(double value) {
/// Convert navigation dir to index [0,1] which allows to
/// store direction dependent objects in std::array<T,2u>
///
/// @param nDir is the navigation direction at input
///
/// returns either 0 or 1
inline constexpr size_t indexFromDirection(NavigationDirection nDir) {
if (nDir == NavigationDirection::Backward) {
return 0u;
}
return 1u;
}

/// Convert and ndex [0,1] to a navigation direction
/// for sorting in std::array<T,2u>
///
/// @param index is the navigation direction at input
///
/// returns either 0 or 1
inline constexpr NavigationDirection directionFromIndex(size_t index) {
if (index == 0u) {
return NavigationDirection::Backward;
}
return NavigationDirection::Forward;
}

/// This turns a signed value into a navigation direction
///
/// @param value is the signed value
///
/// @return a navigation direciton enum
inline constexpr NavigationDirection directionFromStepSize(ActsScalar value) {
assert(value != 0);
return value > 0 ? NavigationDirection::Forward
: NavigationDirection::Backward;
}

/// Invert a navigation direction enum
///
/// @param nDir is the navigation direction at input
///
/// return an opposite navigation direction
inline constexpr NavigationDirection invertDirection(NavigationDirection nDir) {
return (nDir == NavigationDirection::Forward) ? NavigationDirection::Backward
: NavigationDirection::Forward;
}

std::ostream& operator<<(std::ostream& os, NavigationDirection navDir);

// NavigationDirection * T
Expand Down
160 changes: 160 additions & 0 deletions Core/include/Acts/Geometry/Detector.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
// This file is part of the Acts project.
//
// Copyright (C) 2022 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/Definitions/Algebra.hpp"
#include "Acts/Definitions/Common.hpp"
#include "Acts/Geometry/DetectorVolume.hpp"
#include "Acts/Geometry/GeometryContext.hpp"
#include "Acts/Geometry/NavigationDelegates.hpp"
#include "Acts/Utilities/Delegate.hpp"

#include <memory>
#include <stdexcept>
#include <string>
#include <unordered_map>
#include <vector>

namespace Acts {

namespace Experimental {

class Detector : public std::enable_shared_from_this<Detector> {
protected:
/// Create a detector from volumes
///
/// @param name the detecor name
/// @param volumes the objets contained by this detector
/// @param volumeFinder is a Delegate to find the assocaited volume
///
/// @note will throw an exception if volumes vector is empty
/// @note will throw an exception if duplicate volume names exist
/// @note will throw an exception if the delegate is not connected
Detector(const std::string& name,
const std::vector<std::shared_ptr<DetectorVolume>>& volumes,
DetectorVolumeUpdator&& volumeFinder) noexcept(false);

public:
/// Factory for producing memory managed instances of Detector.
/// Will forward all parameters and will attempt to find a suitable
/// constructor.
///
/// @tparam Args the arguments that will be forwarded
template <typename... Args>
static std::shared_ptr<Detector> makeShared(Args&&... args) {
return std::shared_ptr<Detector>(new Detector(std::forward<Args>(args)...));
}

/// Retrieve a @c std::shared_ptr for this surface (non-const version)
///
/// @note Will error if this was not created through the @c makeShared factory
/// since it needs access to the original reference. In C++14 this is
/// undefined behavior (but most likely implemented as a @c bad_weak_ptr
/// exception), in C++17 it is defined as that exception.
/// @note Only call this if you need shared ownership of this object.
///
/// @return The shared pointer
std::shared_ptr<Detector> getSharedPtr();

/// Retrieve a @c std::shared_ptr for this surface (const version)
///
/// @note Will error if this was not created through the @c makeShared factory
/// since it needs access to the original reference. In C++14 this is
/// undefined behavior, but most likely implemented as a @c bad_weak_ptr
/// exception, in C++17 it is defined as that exception.
/// @note Only call this if you need shared ownership of this object.
///
/// @return The shared pointer
std::shared_ptr<const Detector> getSharedPtr() const;

/// Non-const access to the volumes
///
/// @return the volumes shared pointer store
std::vector<std::shared_ptr<DetectorVolume>>& volumePtrs();

/// Const access to sub volumes
///
/// @return a vector to const DetectorVolume raw pointers
const std::vector<const DetectorVolume*>& volumes() const;

/// Update the current volume of a given navigation state
///
/// @param gctx is the Geometry context of the call
/// @param nState [in, out] is the navigation state
///
void updateDetectorVolume(const GeometryContext& gctx,
NavigationState& nState) const;

/// Find a volume from a position
///
/// @param gctx is the Geometry context of the call
/// @param position is the position of the call
///
/// @note this creates internally a NavigationState object
///
/// @return the volume pointer or nullptr (if outside)
const DetectorVolume* findDetectorVolume(const GeometryContext& gctx,
const Vector3& position) const;

/// Find a volume by name
///
/// @param name with which the volume is searched for
///
/// @return the volume pointer or nullptr (if not found)
const DetectorVolume* findDetectorVolume(const std::string& name) const;

/// Update the volume finder
///
/// @param mVolumeFinder the new volume finder
void updateDetectorVolumeFinder(DetectorVolumeUpdator&& mVolumeFinder);

/// Const access to the volume finder
const DetectorVolumeUpdator& detectorVolumeFinder() const;

/// Return the name of the detector
const std::string& name() const;

private:
/// Name of the detector
std::string m_name = "Unnamed";

/// Volume store (internal/external)
DetectorVolume::ObjectStore<std::shared_ptr<DetectorVolume>> m_volumes;

/// A volume finder delegate
DetectorVolumeUpdator m_volumeFinder;

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

inline std::vector<std::shared_ptr<DetectorVolume>>& Detector::volumePtrs() {
return m_volumes.internal;
}

inline const std::vector<const DetectorVolume*>& Detector::volumes() const {
return m_volumes.external;
}

inline void Detector::updateDetectorVolumeFinder(
DetectorVolumeUpdator&& mVolumeFinder) {
m_volumeFinder = std::move(mVolumeFinder);
}

inline const DetectorVolumeUpdator& Detector::detectorVolumeFinder() const {
return m_volumeFinder;
}

inline const std::string& Detector::name() const {
return m_name;
}

} // namespace Experimental

} // namespace Acts
Loading

0 comments on commit 3898a7f

Please sign in to comment.