ATLAS Offline Software
Loading...
Searching...
No Matches
BoundsExpander.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
5
6#ifndef SIMULATIONBASE
7
15
16#include "Acts/Geometry/TrackingVolume.hpp"
17#include "Acts/Geometry/CuboidVolumeBounds.hpp"
18#include "Acts/Geometry/TrapezoidVolumeBounds.hpp"
19#include "Acts/Surfaces/RectangleBounds.hpp"
20#include "Acts/Surfaces/TrapezoidBounds.hpp"
21
22#include <ranges>
23
24namespace MuonGMR4 {
25 BoundsExpander::BoundsExpander(const Acts::Transform3& toVolume,
26 std::unique_ptr<const Acts::Logger> loggerObj):
27 m_toVolume{toVolume} {
28 if (loggerObj) {
29 m_logger = std::move(loggerObj);
30 }
31 }
32 void BoundsExpander::expand(const Acts::GeometryContext& tgContext,
33 const MuonGMR4::Chamber& chamber) {
34 expand(tgContext, *chamber.boundingVolume());
35 }
36 const Acts::Logger& BoundsExpander::logger() const { return *m_logger; }
37
38 void BoundsExpander::expand(const Acts::GeometryContext& tgContext,
39 const MuonGMR4::SpectrometerSector& sector) {
40 expand(tgContext, *sector.boundingVolume());
41 }
42 const Acts::Transform3& BoundsExpander::boxMidPoint() const {
43 return m_shiftTrf;
44 }
45 std::shared_ptr<Acts::VolumeBounds>
47 Acts::VolumeBoundFactory& boundFactory) {
48 switch(readoutElement.detectorType()) {
50 const auto& techEle = static_cast<const MdtReadoutElement&>(readoutElement);
51 const auto& pars = techEle.getParameters();
52 if (std::abs(pars.shortHalfX - pars.longHalfX) < Acts::s_epsilon) {
53 return boundFactory.makeBounds<Acts::CuboidVolumeBounds>(pars.shortHalfX, pars.halfY, pars.halfHeight);
54 }
55 return boundFactory.makeBounds<Acts::TrapezoidVolumeBounds>(pars.shortHalfX, pars.longHalfX,
56 pars.halfY, pars.halfHeight);
58 const auto& techEle = static_cast<const RpcReadoutElement&>(readoutElement);
59 const auto& pars = techEle.getParameters();
60 return boundFactory.makeBounds<Acts::CuboidVolumeBounds>(pars.halfWidth, pars.halfLength, pars.halfThickness);
62 const auto& techEle = static_cast<const TgcReadoutElement&>(readoutElement);
63 const auto& pars = techEle.getParameters();
64 return boundFactory.makeBounds<Acts::TrapezoidVolumeBounds>(pars.halfWidthShort, pars.halfWidthLong,
65 pars.halfHeight, pars.halfThickness );
67 const auto& techEle = static_cast<const sTgcReadoutElement&>(readoutElement);
68 const auto& pars = techEle.getParameters();
69 return boundFactory.makeBounds<Acts::TrapezoidVolumeBounds>(pars.sHalfChamberLength, pars.lHalfChamberLength,
70 pars.halfChamberHeight, pars.halfChamberTck );
72 const auto& techEle = static_cast<const MmReadoutElement&>(readoutElement);
73 const auto& pars = techEle.getParameters();
74 return boundFactory.makeBounds<Acts::TrapezoidVolumeBounds>(pars.halfShortWidth, pars.halfLongWidth,
75 pars.halfHeight, pars.halfThickness );
76 } default:
77 THROW_EXCEPTION("Unsupported detector type "<<readoutElement.detectorType());
78 }
79 return nullptr;
80 }
81 void BoundsExpander::expand(const Acts::GeometryContext& tgContext,
82 const MuonGMR4::MuonReadoutElement& readoutElement,
83 Acts::VolumeBoundFactory& boundFactory) {
84 expand(tgContext, Acts::Volume{readoutElement.localToGlobalTransform(tgContext),
85 makeBounds(readoutElement, boundFactory)});
86 }
87
88 Acts::Transform3 BoundsExpander::toVertexCenter() const {
89 return m_shiftTrf.inverse() * m_toVolume;
90 }
91 void BoundsExpander::reCenter(std::span<const Amg::Vector3D> vertices) {
92 ACTS_VERBOSE(__func__<<"() "<<__LINE__<<" - User defined center system: "
94 for (const Amg::Vector3D& vert : vertices) {
95 const Amg::Vector3D locVert = m_toVolume* vert;
96 for (std::size_t k = 0; k < m_locMax.size(); ++k) {
97 m_locMax[k] = std::max(m_locMax[k], locVert[k]);
98 m_locMin[k] = std::min(m_locMin[k], locVert[k]);
99 }
100 }
101 Amg::Vector3D shiftVec{Amg::Vector3D::Zero()};
102 for (std::size_t k =0 ; k < m_locMax.size(); ++k) {
103 shiftVec[k] = 0.5*(m_locMax[k] + m_locMin[k]);
104 }
106 ACTS_VERBOSE(__func__<<"() "<<__LINE__<<" - New transform: "<<Amg::toString(m_shiftTrf));
107 }
108 std::span<const double> BoundsExpander::minima() const {
109 return m_locMin;
110 }
111 std::span<const double> BoundsExpander::maxima() const {
112 return m_locMax;
113 }
114 std::vector<Amg::Vector3D> BoundsExpander::cornerPoints(const Acts::GeometryContext& tgContext,
115 const Acts::Volume& volume,
116 const std::size_t nSegments) {
117 std::vector<Amg::Vector3D> edges{};
118 const Acts::VolumeBounds& bounds{volume.volumeBounds()};
119 const Acts::Transform3& trf{volume.localToGlobalTransform(tgContext)};
120 for (const Acts::OrientedSurface& boundary : bounds.orientedSurfaces(trf)) {
121 std::vector<Amg::Vector3D> corners = cornerPoints(tgContext, *boundary.surface, nSegments);
122 edges.insert(edges.end(), std::make_move_iterator(corners.begin()),
123 std::make_move_iterator(corners.end()));
124 }
125 auto [begin, end] = std::ranges::unique(edges, [](const Amg::Vector3D& a, const Amg::Vector3D& b) {
126 return (a - b).mag2() < Acts::s_onSurfaceTolerance;
127 });
128 edges.erase(begin, end);
129 return edges;
130 }
131 std::vector<Amg::Vector3D> BoundsExpander::cornerPoints(const Acts::GeometryContext& tgContext,
132 const Acts::Surface& surface,
133 const std::size_t nSegments) {
134 constexpr std::array signs{-1., 1.};
135 std::vector<Amg::Vector3D> vertices{}; //vertices has size zero
136 //calculate transform once, outside of loops
137 const Acts::Transform3& transform = surface.localToGlobalTransform(tgContext);
141 switch (surface.bounds().type()) {
142 using enum Acts::SurfaceBounds::BoundsType;
143 case eRectangle: {
144 const auto& bounds{static_cast<const Acts::RectangleBounds&>(surface.bounds())};
145 using enum Acts::RectangleBounds::BoundValues;
146 const double stepX = 2.*bounds.get(eMaxX) / nSegments;
147 const double stepY = 2.*bounds.get(eMaxY) / nSegments;
148 for (const double sign : signs) {
149 for (unsigned seg = 0; seg <= nSegments ; ++seg) {
150 vertices.push_back(transform *
151 Amg::Vector3D{-bounds.get(eMaxX) + stepX * seg,
152 sign*bounds.get(eMaxY), 0.});
153 vertices.push_back(transform *
154 Amg::Vector3D{sign*bounds.get(eMaxX),
155 -bounds.get(eMaxY) + stepY * seg, 0.});
156 }
157 }
158 break;
159 } case eTrapezoid: {
160 const auto& bounds{static_cast<const Acts::TrapezoidBounds&>(surface.bounds())};
161 using enum Acts::TrapezoidBounds::BoundValues;
162 const double hY = bounds.get(eHalfLengthY);
163 const double xS = bounds.get(eHalfLengthXnegY);
164 const double xL = bounds.get(eHalfLengthXposY);
165 const double m = (xL - xS) / (2.*hY);
166 Amg::Vector3D locPos{Amg::Vector3D::Zero()};
167 auto pushVertex = [&](const double x, const double y) {
168 locPos.block<2,1>(0,0) = Eigen::Rotation2D{-bounds.get(eRotationAngle)} *
170 vertices.push_back(transform *locPos);
171 };
172 const double stepY = 2.*hY / nSegments;
173 for (const double sign : signs) {
174 const double x = (sign > 0 ? xL : xS);
175 const double stepX = 2.*x / nSegments;
176 for (unsigned seg = 0; seg <= nSegments ; ++seg){
177 pushVertex(-x + stepX*seg, sign*hY);
178 const double y = -hY + stepY*seg;
179 pushVertex(sign*(xS + (y+hY)*m), y);
180 }
181 }
182 break;
183 } default: {
184 vertices = surface.polyhedronRepresentation(tgContext, nSegments).vertices;
185 break;
186 }
187 }
188 return vertices;
189 }
190 std::unique_ptr<Acts::TrackingVolume> BoundsExpander::makeEnvelope(Acts::VolumeBoundFactory& factory,
191 std::string_view volName) {
192 auto volume = std::make_unique<Acts::TrackingVolume>(toVertexCenter().inverse(),
193 makeBounds(factory), std::string{volName});
194 ACTS_DEBUG(__func__<<"() "<<__LINE__<<" - Created new volume envelope "
195 <<volName<<" located at @"<<Amg::toString(toVertexCenter().inverse())
196 <<" with bounds: "<<volume->volumeBounds());
197 return volume;
198 }
199}
200#endif
static Double_t a
int sign(int a)
#define y
#define x
virtual DetectorType detectorType() const =0
Returns the detector element type.
static std::vector< Amg::Vector3D > cornerPoints(const Acts::GeometryContext &tgContext, const Acts::Volume &volume, const std::size_t nSegments=3)
Returns the vertices from a volume.
std::span< const double > maxima() const
Returns the triplet of the maximum coordinates from the ensemble of all seen vertices.
std::array< double, 3 > m_locMin
Minimum value seen by the recenter method.
Acts::Transform3 m_shiftTrf
Extra shift to center all the vertices.
std::span< const double > minima() const
Returns the triplet of the minimum coordinates from the ensemble of all seen vertices.
Acts::Transform3 toVertexCenter() const
Returns the transform from the ATLAS frame to the center of all seen vertices.
BoundsExpander()=default
Default constructor.
Acts::Transform3 m_toVolume
External method to go from ATLAS to the reference frame.
std::array< double, 3 > m_locMax
Maximum value seen by the recenter method.
void expand(const Acts::GeometryContext &tgContext, const MuonGMR4::Chamber &chamber)
Expand the bounds from a chamber.
static std::shared_ptr< Acts::VolumeBounds > makeBounds(const MuonGMR4::MuonReadoutElement &readoutElement, Acts::VolumeBoundFactory &boundFactory)
Crate volume bounds that enclose the readout element from the central localToGlobalTransform.
std::unique_ptr< const Acts::Logger > m_logger
const Acts::Transform3 & boxMidPoint() const
Returns the transform from the nominal volume center to the middle point to all seen vertices.
const Acts::Logger & logger() const
Returns the ACTS logegr object.
void reCenter(std::span< const Amg::Vector3D > vertices)
Update the center point from a list of global vertices.
std::unique_ptr< Acts::TrackingVolume > makeEnvelope(Acts::VolumeBoundFactory &factory, std::string_view volName)
Creates an empty tracking volume.
Chamber represent the volume enclosing a muon station.
Definition Chamber.h:29
Readout element to describe the Monitored Drift Tube (Mdt) chambers Mdt chambers usually comrpise out...
const parameterBook & getParameters() const
Get a const reference to the parameter book.
const parameterBook & getParameters() const
MuonReadoutElement is an abstract class representing the geometry of a muon detector.
const Acts::Transform3 & localToGlobalTransform(const ActsTrk::GeometryContext &ctx) const override final
Returns the transformation from the local coordinate system of the readout element into the global AT...
A spectrometer sector forms the envelope of all chambers that are placed in the same MS sector & laye...
std::shared_ptr< Acts::Volume > boundingVolume() const
Returns the Acts::Volume representation of the sector.
@ Mm
Maybe not needed in the migration.
@ Tgc
Resitive Plate Chambers.
@ sTgc
Micromegas (NSW).
@ Rpc
Monitored Drift Tubes.
@ Mdt
MuonSpectrometer.
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Amg::Isometry3D getTranslate3D(const double X, const double Y, const double Z)
: Returns a shift transformation along an arbitrary axis
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
The ReadoutGeomCnvAlg converts the Run4 Readout geometry build from the GeoModelXML into the legacy M...
#define THROW_EXCEPTION(MESSAGE)
Definition throwExcept.h:10