ATLAS Offline Software
Loading...
Searching...
No Matches
SubtractedVolumeBounds.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6// SubtractedVolumeBounds.cxx, (c) ATLAS Detector software
8
9// Trk
14// TrkSurfaces
23#include "TrkSurfaces/Surface.h"
25#include "TrkVolumes/Volume.h"
26// Gaudi
27#include "GaudiKernel/MsgStream.h"
28// STD
29#include <cmath>
30#include <iostream>
31#include <utility>
32
34
35Trk::SubtractedVolumeBounds::SubtractedVolumeBounds(std::unique_ptr<Volume> vol1, std::unique_ptr<Volume> vol2)
36 : VolumeBounds()
37 , m_outer(std::move(vol1))
38 , m_inner(std::move(vol2))
41{}
42
51
53
56{
57 if (this != &bobo) {
58 m_outer.reset(bobo.m_outer->clone());
59 m_inner.reset(bobo.m_inner->clone());
62 }
63 return *this;
64}
65
66std::vector<std::unique_ptr<Trk::Surface>>
68 const Amg::Transform3D& transf) {
69 // double tol=0.001;
70 // get surfaces for outer boundaries
71 std::vector<std::unique_ptr<Trk::Surface>> outerSurfaces =
72 m_outer->volumeBounds().decomposeToSurfaces(transf * m_outer->transform());
73 // get surfaces for inner boundaries
74 std::vector<std::unique_ptr<Trk::Surface>> innerSurfaces =
75 m_inner->volumeBounds().decomposeToSurfaces(transf * m_inner->transform());
76 std::vector<unsigned int> subtrInner;
77
78
79 auto retsf = std::vector<std::unique_ptr<Trk::Surface>>();
80
81 unsigned int nSurf = outerSurfaces.size() + innerSurfaces.size();
82 m_boundsOrientation.resize(nSurf);
83
84 const Trk::CylinderVolumeBounds* cylVol = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(m_outer->volumeBounds()));
85 const Trk::SimplePolygonBrepVolumeBounds* spbVol = dynamic_cast<const Trk::SimplePolygonBrepVolumeBounds*>(&(m_outer->volumeBounds()));
86 const Trk::CombinedVolumeBounds* comVol = dynamic_cast<const Trk::CombinedVolumeBounds*>(&(m_outer->volumeBounds()));
87 const Trk::SubtractedVolumeBounds* subVol = dynamic_cast<const Trk::SubtractedVolumeBounds*>(&(m_outer->volumeBounds()));
88
89 // loop over 'outer' boundary surfaces; modified by subtracted volume
90 for (unsigned int out = 0; out < outerSurfaces.size(); out++) {
91 const SubtractedPlaneSurface* splo = dynamic_cast<const SubtractedPlaneSurface*>(outerSurfaces[out].get());
92 const PlaneSurface* plo = dynamic_cast<const PlaneSurface*>(outerSurfaces[out].get());
93 const SubtractedCylinderSurface* sclo = dynamic_cast<const SubtractedCylinderSurface*>(outerSurfaces[out].get());
94 const CylinderSurface* clo = dynamic_cast<const CylinderSurface*>(outerSurfaces[out].get());
95 const DiscSurface* dlo = dynamic_cast<const DiscSurface*>(outerSurfaces[out].get());
96
97 if (!(splo || plo || sclo || clo || dlo)) {
98 throw std::runtime_error("Unhandled surface.");
99 }
100 // resolve bounds orientation : copy from combined/subtracted, swap inner
101 // cyl, swap bottom spb
102 if (comVol){
103 m_boundsOrientation[out] = comVol->boundsOrientation()[out];
104 }
105 else if (subVol){
106 m_boundsOrientation[out] = subVol->boundsOrientation()[out];
107 }
108 else if (cylVol && clo && out == 3){
109 m_boundsOrientation[out] = false;
110 }
111 else if (spbVol && out == 0){
112 m_boundsOrientation[out] = false;
113 }
114 else{
115 m_boundsOrientation[out] = true;
116 }
117 //
118 auto innerSub = std::unique_ptr<Trk::Volume>(createSubtractedVolume(
119 outerSurfaces[out]->transform().inverse() * transf, m_inner.get()));
120
121 if (splo || sclo) { // multiple subtraction
122 const Trk::AreaExcluder* vEx;
123 bool shared = false;
124 if (splo) {
125 vEx = splo->subtractedVolume();
126 shared = splo->shared();
127 }
128 if (sclo) {
129 vEx = sclo->subtractedVolume();
130 shared = sclo->shared();
131 }
132 const Trk::VolumeExcluder* volExcl = dynamic_cast<const Trk::VolumeExcluder*>(vEx);
133 if (!volExcl){
134 throw std::logic_error("Not a VolumeExcluder");
135 }
136
137 auto outerSub = std::make_unique<Trk::Volume>(*volExcl->volume());
138 std::unique_ptr<Trk::Volume> comb_sub;
139 if (!shared){
140 comb_sub = std::make_unique<Trk::Volume>(
141 nullptr,
142 std::make_shared<Trk::CombinedVolumeBounds>(std::move(innerSub), std::move(outerSub), false));
143 } else {
144 comb_sub = std::make_unique<Trk::Volume>(
145 nullptr,
146 std::make_shared<Trk::SubtractedVolumeBounds>(std::move(outerSub), std::move(innerSub)));
147 }
148 auto volEx = std::make_shared<const Trk::VolumeExcluder>(std::move(comb_sub));
149 if (splo){
150 retsf.push_back(std::make_unique<Trk::SubtractedPlaneSurface>(*splo, std::move(volEx), shared));
151 }
152 else if (sclo){
153 retsf.push_back(
154 std::make_unique<Trk::SubtractedCylinderSurface>(*sclo, std::move(volEx), shared));
155 }
156 } else {
157 auto volEx = std::make_shared<const Trk::VolumeExcluder>(std::move(innerSub));
158 if (plo){
159 retsf.push_back(std::make_unique<Trk::SubtractedPlaneSurface>(*plo, std::move(volEx), false));
160 }
161 else if (clo){
162 retsf.push_back(std::make_unique<Trk::SubtractedCylinderSurface>(*clo, std::move(volEx), false));
163 }
164 else if (dlo) {
165 // turn disc into ellipse for simplification
166 const DiscBounds* db = dynamic_cast<const DiscBounds*>(&(dlo->bounds()));
167 if (!db){
168 throw std::logic_error("Not DiscBounds");
169 }
170 auto eb = std::make_shared<EllipseBounds>(db->rMin(), db->rMin(), db->rMax(), db->rMax(), db->halfPhiSector());
171 auto ploA = PlaneSurface(Amg::Transform3D(dlo->transform()), eb);
172 retsf.push_back(std::make_unique<Trk::SubtractedPlaneSurface>(ploA, std::move(volEx), false));
173 }
174 }
175 }
176
177 // loop over 'inner' boundary surfaces; include only if represent a new
178 // surface change: include allways otherwise orientation messed up bonus :
179 // solves 'double boundary' problem
180 cylVol = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(m_inner->volumeBounds()));
181 spbVol = dynamic_cast<const Trk::SimplePolygonBrepVolumeBounds*>(&(m_inner->volumeBounds()));
182 comVol = dynamic_cast<const Trk::CombinedVolumeBounds*>(&(m_inner->volumeBounds()));
183 subVol = dynamic_cast<const Trk::SubtractedVolumeBounds*>(&(m_inner->volumeBounds()));
184 unsigned int nOut = outerSurfaces.size();
185
186 for (unsigned int in = 0; in < innerSurfaces.size(); in++) {
187 const SubtractedPlaneSurface* spli = dynamic_cast<const SubtractedPlaneSurface*>(innerSurfaces[in].get());
188 const PlaneSurface* pli = dynamic_cast<const PlaneSurface*>(innerSurfaces[in].get());
189 const SubtractedCylinderSurface* scli = dynamic_cast<const SubtractedCylinderSurface*>(innerSurfaces[in].get());
190 const CylinderSurface* cli = dynamic_cast<const CylinderSurface*>(innerSurfaces[in].get());
191 const DiscSurface* dli = dynamic_cast<const DiscSurface*>(innerSurfaces[in].get());
192 // resolve bounds orientation : copy from combined/subtracted, swap inner
193 // cyl, swap bottom spb, swap all
194 if (comVol){
195 m_boundsOrientation[nOut + in] = !comVol->boundsOrientation()[in];
196 }
197 else if (subVol){
198 m_boundsOrientation[nOut + in] = !subVol->boundsOrientation()[in];
199 }
200 else if (cylVol && cli && in == 3){
201 m_boundsOrientation[nOut + in] = true;
202 }
203 else if (spbVol && in == 0){
204 m_boundsOrientation[nOut + in] = true;
205 }
206 else{
207 m_boundsOrientation[nOut + in] = false;
208 }
209 //
210 auto outerSub = std::unique_ptr<Trk::Volume>(createSubtractedVolume(
211 innerSurfaces[in]->transform().inverse() * transf, m_outer.get()));
212
213 if (spli || scli) {
214 bool shared = false;
215 const Trk::AreaExcluder* vEx;
216 if (spli) {
217 vEx = spli->subtractedVolume();
218 shared = spli->shared();
219 }
220 if (scli) {
221 vEx = scli->subtractedVolume();
222 shared = scli->shared();
223 }
224 const Trk::VolumeExcluder* volExcl = dynamic_cast<const Trk::VolumeExcluder*>(vEx);
225 if (!volExcl){
226 throw std::logic_error("Not a VolumeExcluder");
227 }
228
229 auto innerSub = std::make_unique<Trk::Volume>(*volExcl->volume());
230 // combined volume
231 std::unique_ptr<Trk::Volume> comb_sub;
232 if (!shared){
233 comb_sub = std::make_unique<Trk::Volume>(
234 nullptr,
235 std::make_shared<Trk::SubtractedVolumeBounds>(std::move(outerSub), std::move(innerSub)));
236 }
237 else{
238 comb_sub = std::make_unique<Trk::Volume>(
239 nullptr,
240 std::make_shared<Trk::CombinedVolumeBounds>(std::move(innerSub), std::move(outerSub), true));
241 }
242 auto volEx = std::make_shared<const Trk::VolumeExcluder>(std::move(comb_sub));
243 if (spli){
244 retsf.push_back(std::make_unique<Trk::SubtractedPlaneSurface>(*spli, std::move(volEx), true));
245 }
246 else if (scli){
247 retsf.push_back(std::make_unique<Trk::SubtractedCylinderSurface>(*scli, std::move(volEx), true));
248 }
249
250 } else if (pli || cli) {
251 auto volEx = std::make_shared<const Trk::VolumeExcluder>(std::move(outerSub));
252 if (pli){
253 retsf.push_back(std::make_unique<Trk::SubtractedPlaneSurface>(*pli, std::move(volEx), true));
254 }
255 else if (cli){
256 retsf.push_back(std::make_unique<Trk::SubtractedCylinderSurface>(*cli, std::move(volEx), true));
257 }
258 } else if (dli) {
259 // turn disc into ellipse for simplification
260 const DiscBounds* db = dynamic_cast<const DiscBounds*>(&(dli->bounds()));
261 if (!db){
262 throw std::logic_error("Not DiscBounds");
263 }
264 auto eb = std::make_shared<EllipseBounds>(db->rMin(), db->rMin(), db->rMax(), db->rMax(), db->halfPhiSector());
265 PlaneSurface pla(Amg::Transform3D(dli->transform()), eb);
266 auto volEx = std::make_shared<const Trk::VolumeExcluder>(std::move(outerSub));
267 retsf.push_back(std::make_unique<Trk::SubtractedPlaneSurface>(pla, std::move(volEx), true));
268 } else {
269 throw std::runtime_error(
270 "Unhandled surface in "
271 "Trk::SubtractedVolumeBounds::decomposeToSurfaces.");
272 }
273 }
274
275 return retsf;
276}
277
278// ostream operator overload
279
280MsgStream&
282{
283 std::stringstream temp_sl;
284 temp_sl << std::setiosflags(std::ios::fixed);
285 temp_sl << std::setprecision(7);
286 temp_sl << "Trk::SubtractedVolumeBounds: outer,inner ";
287 sl << temp_sl.str();
288 std::as_const(*m_outer).volumeBounds().dump(sl);
289 std::as_const(*m_inner).volumeBounds().dump(sl);
290 return sl;
291}
292
293std::ostream&
295{
296 std::stringstream temp_sl;
297 temp_sl << std::setiosflags(std::ios::fixed);
298 temp_sl << std::setprecision(7);
299 temp_sl << "Trk::SubtractedVolumeBounds: outer,inner ";
300 sl << temp_sl.str();
301 std::as_const(*m_outer).volumeBounds().dump(sl);
302 std::as_const(*m_inner).volumeBounds().dump(sl);
303 return sl;
304}
305
308 const Amg::Transform3D& transf,
309 Trk::Volume* subtrVol)
310{
311 if (!subtrVol){
312 return nullptr;
313 }
314 return new Trk::Volume(*subtrVol, transf);
315}
316
Pure abstract base class.
Bounds for a generic combined volume, the decomposeToSurfaces method creates a vector of n surfaces (...
const std::vector< bool > & boundsOrientation() const
This method returns bounds orientation.
Class for a CylinderSurface in the ATLAS detector.
Bounds for a cylindrical Volume, the decomposeToSurfaces method creates a vector of up to 6 surfaces:
Class to describe the bounds for a planar DiscSurface.
Definition DiscBounds.h:44
Class for a DiscSurface in the ATLAS detector.
Definition DiscSurface.h:54
const SurfaceBounds & bounds() const override final
This method returns the bounds by reference.
Class for a planaer rectangular or trapezoidal surface in the ATLAS detector.
Bounds for the exact transcript of the GeoSimplePolygonBrep; volume defined by combination of symm....
Class for a cylinder subtracted/shared surface in the ATLAS detector.
const AreaExcluder * subtractedVolume() const
This method allows access to the subtracted part.
bool shared() const
This method indicates the subtraction mode.
Class for a planar subtracted/shared surface in the ATLAS detector.
bool shared() const
This method indicates the subtraction mode.
const AreaExcluder * subtractedVolume() const
This method allows access to the subtracted part.
Bounds for a generic subtracted volume, the decomposeToSurfaces method creates a vector of n surfaces...
SubtractedVolumeBounds()
Default Constructor.
EightObjectsAccessor m_objectAccessor
There's only one single object Acessor for the moment has to be implemented if Subtracteds are used m...
const std::vector< bool > & boundsOrientation() const
This method returns bounds orientation.
std::unique_ptr< Volume > m_inner
std::unique_ptr< Volume > m_outer
SubtractedVolumeBounds * clone() const override final
Virtual constructor.
virtual ~SubtractedVolumeBounds()
Destructor.
static Trk::Volume * createSubtractedVolume(const Amg::Transform3D &transf, Trk::Volume *subtrVol)
MsgStream & dump(MsgStream &sl) const override
Output Method for MsgStream.
virtual std::vector< std::unique_ptr< Trk::Surface > > decomposeToSurfaces(const Amg::Transform3D &transform) override final
Method to decompose the Bounds into boundarySurfaces.
SubtractedVolumeBounds & operator=(const SubtractedVolumeBounds &bobo)
Assignment operator.
std::vector< bool > m_boundsOrientation
const Amg::Transform3D & transform() const
Returns HepGeom::Transform3D by reference.
VolumeBounds()
Default Constructor.
removes explicit dependence of Subtracted*Surface on TrkVolumes
const Volume * volume() const
Acces the subtracted volume.
Base class for all volumes inside the tracking realm, it defines the interface for inherited Volume c...
Definition Volume.h:36
Eigen::Affine3d Transform3D
STL namespace.