ATLAS Offline Software
CombinedVolumeBounds.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 // CombinedVolumeBounds.cxx, (c) ATLAS Detector software
8 
9 // Trk
11 
16 // TrkSurfaces
20 #include "TrkSurfaces/DiscBounds.h"
25 #include "TrkSurfaces/Surface.h"
26 // Gaudi
27 #include "GaudiKernel/MsgStream.h"
28 // STD
29 #include <cmath>
30 #include <iostream>
31 #include <stdexcept>
32 #include <utility>
33 
35 
37  std::unique_ptr<Volume> vol1,
38  std::unique_ptr<Volume> vol2,
39  bool intersection)
40  : VolumeBounds()
41  , m_first(std::move(vol1))
42  , m_second(std::move(vol2))
43  , m_intersection(intersection)
44  , m_objectAccessor()
45  , m_boundsOrientation()
46 {}
47 
49  const Trk::CombinedVolumeBounds& bobo)
50  : VolumeBounds()
51  , m_first{bobo.m_first->clone()}
52  , m_second{bobo.m_second->clone()}
53  , m_intersection(bobo.m_intersection)
54  , m_objectAccessor(bobo.m_objectAccessor)
55  , m_boundsOrientation(bobo.m_boundsOrientation)
56 {}
57 
59 
62 {
63  if (this != &bobo) {
64  m_first.reset(bobo.m_first->clone());
65  m_second.reset(bobo.m_second->clone());
66  m_intersection = bobo.m_intersection;
67  m_objectAccessor = bobo.m_objectAccessor;
68  m_boundsOrientation = bobo.m_boundsOrientation;
69  }
70  return *this;
71 }
72 
73 std::vector<std::unique_ptr<Trk::Surface>>
75 
76  auto retsf = std::vector<std::unique_ptr<Trk::Surface>>();
77 
78  const Trk::CylinderVolumeBounds* cylVol = dynamic_cast<const Trk::CylinderVolumeBounds*>(&(m_first->volumeBounds()));
79  const Trk::SimplePolygonBrepVolumeBounds* spbVol = dynamic_cast<const Trk::SimplePolygonBrepVolumeBounds*>(&(m_first->volumeBounds()));
80  const Trk::CombinedVolumeBounds* comVol = dynamic_cast<const Trk::CombinedVolumeBounds*>(&(m_first->volumeBounds()));
81  const Trk::SubtractedVolumeBounds* subVol = dynamic_cast<const Trk::SubtractedVolumeBounds*>(&(m_first->volumeBounds()));
82 
83  // get surfaces for first boundaries
84  std::vector<std::unique_ptr<Trk::Surface>> firstSurfaces =
85  m_first->volumeBounds().decomposeToSurfaces(transf * m_first->transform());
86  // get surfaces for second boundaries
87  std::vector<std::unique_ptr<Trk::Surface>> secondSurfaces =
88  m_second->volumeBounds().decomposeToSurfaces(transf * m_second->transform());
89  unsigned int nSurf = firstSurfaces.size() + secondSurfaces.size();
90  m_boundsOrientation.resize(nSurf);
91 
92  std::vector<unsigned int> subtrSecond;
93 
94  // loop over surfaces; convert disc surface to a plane surface using elliptic
95  // bounds
96  for (unsigned int out = 0; out < firstSurfaces.size(); out++) {
97  //
98  const SubtractedPlaneSurface* splo = dynamic_cast<const SubtractedPlaneSurface*>(firstSurfaces[out].get());
99  const PlaneSurface* plo = dynamic_cast<const PlaneSurface*>(firstSurfaces[out].get());
100  const SubtractedCylinderSurface* sclo = dynamic_cast<const SubtractedCylinderSurface*>(firstSurfaces[out].get());
101  const CylinderSurface* clo = dynamic_cast<const CylinderSurface*>(firstSurfaces[out].get());
102  const DiscSurface* dlo = dynamic_cast<const DiscSurface*>(firstSurfaces[out].get());
103 
104  // resolve bounds orientation : copy from combined/subtracted, swap inner
105  // cyl, swap bottom spb
106  if (comVol){
107  m_boundsOrientation[out] = comVol->boundsOrientation()[out];
108  }
109  else if (subVol){
110  m_boundsOrientation[out] = subVol->boundsOrientation()[out];
111  }
112  else if (cylVol && clo && out == 3){
113  m_boundsOrientation[out] = false;
114  }
115  else if (spbVol && out == 0){
116  m_boundsOrientation[out] = false;
117  }
118  else{
119  m_boundsOrientation[out] = true;
120  }
121 
122  std::unique_ptr<Trk::Volume> secondSub(createSubtractedVolume(
123  firstSurfaces[out]->transform().inverse() * transf, m_second.get()));
124 
125  if (sclo || splo) {
126  bool shared = false;
127  const Trk::AreaExcluder* vEx;
128  if (splo) {
129  vEx = splo->subtractedVolume();
130  shared = splo->shared();
131  }
132  if (sclo) {
133  vEx = sclo->subtractedVolume();
134  shared = sclo->shared();
135  }
136  const Trk::VolumeExcluder* volExcl = dynamic_cast<const Trk::VolumeExcluder*>(vEx);
137  if (!volExcl){
138  throw std::logic_error("Not a VolumeExcluder");
139  }
140 
141  auto firstSub = std::make_unique<Trk::Volume>(*volExcl->volume());
142 
143  std::unique_ptr<Trk::Volume> comb_sub{};
144  if (!shared && !m_intersection){
145  comb_sub = std::make_unique<Trk::Volume>(
146  nullptr,
147  std::make_shared<Trk::CombinedVolumeBounds>(std::move(secondSub), std::move(firstSub), m_intersection));
148  }
149  if (!shared && m_intersection){
150  comb_sub = std::make_unique<Trk::Volume>(
151  nullptr,
152  std::make_shared<Trk::SubtractedVolumeBounds>(std::move(secondSub), std::move(firstSub)));
153  }
154  if (shared && m_intersection){
155  comb_sub = std::make_unique<Trk::Volume>(
156  nullptr,
157  std::make_shared<Trk::CombinedVolumeBounds>(std::move(secondSub), std::move(firstSub), m_intersection));
158  }
159  if (shared && !m_intersection){
160  comb_sub = std::make_unique<Trk::Volume>(
161  nullptr,
162  std::make_shared<Trk::SubtractedVolumeBounds>(std::move(firstSub), std::move(secondSub)));
163  }
164  auto volEx = std::make_shared<const Trk::VolumeExcluder>(std::move(comb_sub));
165  bool new_shared = shared;
166  if (m_intersection){
167  new_shared = true;
168  }
169  if (splo){
170  retsf.push_back(std::make_unique<Trk::SubtractedPlaneSurface>(*splo, std::move(volEx), new_shared));
171  }
172  else if (sclo){
173  retsf.push_back(std::make_unique<Trk::SubtractedCylinderSurface>(*sclo, std::move(volEx), new_shared));
174  }
175  } else if (plo || clo || dlo) {
176  auto volEx = std::make_shared<const Trk::VolumeExcluder>(std::move(secondSub));
177  if (plo){
178  retsf.push_back(std::make_unique<Trk::SubtractedPlaneSurface>(*plo, std::move(volEx), m_intersection));
179  }
180  else if (clo){
181  retsf.push_back(std::make_unique<Trk::SubtractedCylinderSurface>(*clo, std::move(volEx), m_intersection));
182  }
183  else if (dlo) {
184  const DiscBounds* db = dynamic_cast<const DiscBounds*>(&(dlo->bounds()));
185  if (!db){
186  throw std::logic_error("Not DiscBounds");
187  }
188  auto eb = std::make_shared<EllipseBounds>(db->rMin(), db->rMin(), db->rMax(), db->rMax(), db->halfPhiSector());
189  retsf.push_back( std::make_unique<Trk::SubtractedPlaneSurface>(
191  std::move(volEx),
192  m_intersection));
193  }
194  } else {
195  throw std::runtime_error(
196  "Unhandled surface in CombinedVolumeBounds::decomposeToSurfaces.");
197  }
198  }
199 
200  cylVol =
201  dynamic_cast<const Trk::CylinderVolumeBounds*>(&(m_second->volumeBounds()));
202  spbVol = dynamic_cast<const Trk::SimplePolygonBrepVolumeBounds*>(
203  &(m_second->volumeBounds()));
204  comVol =
205  dynamic_cast<const Trk::CombinedVolumeBounds*>(&(m_second->volumeBounds()));
206  subVol = dynamic_cast<const Trk::SubtractedVolumeBounds*>(
207  &(m_second->volumeBounds()));
208  unsigned int nOut = firstSurfaces.size();
209 
210  for (unsigned int in = 0; in < secondSurfaces.size(); in++) {
211  //
212  const SubtractedPlaneSurface* spli = dynamic_cast<const SubtractedPlaneSurface*>(secondSurfaces[in].get());
213  const PlaneSurface* pli = dynamic_cast<const PlaneSurface*>(secondSurfaces[in].get());
214  const SubtractedCylinderSurface* scli = dynamic_cast<const SubtractedCylinderSurface*>(secondSurfaces[in].get());
215  const CylinderSurface* cli = dynamic_cast<const CylinderSurface*>(secondSurfaces[in].get());
216  const DiscSurface* dli = dynamic_cast<const DiscSurface*>(secondSurfaces[in].get());
217 
218  // resolve bounds orientation : copy from combined/subtracted, swap inner
219  // cyl, swap bottom spb
220  if (comVol){
221  m_boundsOrientation[nOut + in] = comVol->boundsOrientation()[in];
222  }
223  else if (subVol){
224  m_boundsOrientation[nOut + in] = subVol->boundsOrientation()[in];
225  }
226  else if (cylVol && cli && in == 3){
227  m_boundsOrientation[nOut + in] = false;
228  }
229  else if (spbVol && in == 0){
230  m_boundsOrientation[nOut + in] = false;
231  }
232  else{
233  m_boundsOrientation[nOut + in] = true;
234  }
235 
236  std::unique_ptr<Trk::Volume> firstSub(createSubtractedVolume(
237  secondSurfaces[in]->transform().inverse() * transf, m_first.get()));
238  if (scli || spli) {
239  bool shared = false;
240  const Trk::AreaExcluder* vEx;
241  if (spli) {
242  vEx = spli->subtractedVolume();
243  shared = spli->shared();
244  }
245  if (scli) {
246  vEx = scli->subtractedVolume();
247  shared = scli->shared();
248  }
249  const Trk::VolumeExcluder* volExcl = dynamic_cast<const Trk::VolumeExcluder*>(vEx);
250  if (!volExcl){
251  throw std::logic_error("Not a VolumeExcluder");
252  }
253  auto secondSub = std::make_unique<Trk::Volume>(*volExcl->volume());
254 
255  std::unique_ptr<Trk::Volume> comb_sub{};
256  if (!shared && !m_intersection){
257  comb_sub = std::make_unique<Trk::Volume>(
258  nullptr,
259  std::make_shared<Trk::CombinedVolumeBounds>(std::move(firstSub), std::move(secondSub), m_intersection));
260  }
261  if (!shared && m_intersection){
262  comb_sub = std::make_unique<Trk::Volume>(
263  nullptr,
264  std::make_shared<Trk::SubtractedVolumeBounds>(std::move(firstSub), std::move(secondSub)));
265  }
266  if (shared && m_intersection){
267  comb_sub = std::make_unique<Trk::Volume>(
268  nullptr,
269  std::make_shared<Trk::CombinedVolumeBounds>(std::move(firstSub), std::move(secondSub), m_intersection));
270  }
271  if (shared && !m_intersection){
272  comb_sub = std::make_unique<Trk::Volume>(
273  nullptr,
274  std::make_shared<Trk::SubtractedVolumeBounds>(std::move(secondSub), std::move(firstSub)));
275  }
276  auto volEx = std::make_shared<const Trk::VolumeExcluder>(std::move(comb_sub));
277  bool new_shared = shared;
278  if (m_intersection){
279  new_shared = true;
280  }
281  if (spli){
282  retsf.push_back(std::make_unique<Trk::SubtractedPlaneSurface>(*spli, std::move(volEx), new_shared));
283  }
284  else if (scli)
285  retsf.push_back( std::make_unique<Trk::SubtractedCylinderSurface>(*scli, std::move(volEx), new_shared));
286 
287  } else if (pli || cli || dli) {
288  auto volEx = std::make_shared<const Trk::VolumeExcluder>(std::move(firstSub));
289  if (pli){
290  retsf.push_back(std::make_unique<Trk::SubtractedPlaneSurface>(*pli, std::move(volEx), m_intersection));
291  }
292  else if (cli){
293  retsf.push_back(std::make_unique<Trk::SubtractedCylinderSurface>(*cli, std::move(volEx), m_intersection));
294  }
295  else if (dli) {
296  const DiscBounds* db = dynamic_cast<const DiscBounds*>(&(dli->bounds()));
297  if (!db){
298  throw std::logic_error("Not DiscBounds");
299  }
300  auto eb = std::make_shared<EllipseBounds>(db->rMin(), db->rMin(), db->rMax(), db->rMax(), db->halfPhiSector());
301  auto pliN = PlaneSurface(Amg::Transform3D(dli->transform()), eb);
302  retsf.push_back(std::make_unique<Trk::SubtractedPlaneSurface>(pliN, std::move(volEx), m_intersection));
303  }
304  } else {
305  throw std::runtime_error(
306  "Unhandled surface in CombinedVolumeBounds::decomposeToSurfaces.");
307  }
308  }
309  return retsf;
310 }
311 
312 // ostream operator overload
313 
314 MsgStream&
316 {
317  std::stringstream temp_sl;
318  temp_sl << std::setiosflags(std::ios::fixed);
319  temp_sl << std::setprecision(7);
320  temp_sl << "Trk::CombinedVolumeBounds: first,second ";
321  sl << temp_sl.str();
322  std::as_const(*m_first).volumeBounds().dump(sl);
323  std::as_const(*m_second).volumeBounds().dump(sl);
324  return sl;
325 }
326 
327 std::ostream&
328 Trk::CombinedVolumeBounds::dump(std::ostream& sl) const
329 {
330  std::stringstream temp_sl;
331  temp_sl << std::setiosflags(std::ios::fixed);
332  temp_sl << std::setprecision(7);
333  temp_sl << "Trk::CombinedVolumeBounds: first,second ";
334  sl << temp_sl.str();
335  std::as_const(*m_first).volumeBounds().dump(sl);
336  std::as_const(*m_second).volumeBounds().dump(sl);
337  return sl;
338 }
339 
342  const Amg::Transform3D& transf,
343  const Trk::Volume* subtrVol)
344 {
345  if (!subtrVol){
346  return nullptr;
347  }
348  return new Trk::Volume(*subtrVol, transf);
349 }
350 
Trk::SubtractedPlaneSurface::subtractedVolume
const AreaExcluder * subtractedVolume() const
This method allows access to the subtracted part.
EllipseBounds.h
Trk::SubtractedCylinderSurface::shared
bool shared() const
This method indicates the subtraction mode.
Trk::CombinedVolumeBounds::createSubtractedVolume
static Trk::Volume * createSubtractedVolume(const Amg::Transform3D &transf, const Trk::Volume *subtrVol)
Definition: CombinedVolumeBounds.cxx:341
Trk::SubtractedVolumeBounds::boundsOrientation
const std::vector< bool > & boundsOrientation() const
This method returns bounds orientation.
Definition: SubtractedVolumeBounds.h:122
DiscBounds.h
Trk::CombinedVolumeBounds::m_boundsOrientation
std::vector< bool > m_boundsOrientation
Definition: CombinedVolumeBounds.h:105
Trk::CombinedVolumeBounds::operator=
CombinedVolumeBounds & operator=(const CombinedVolumeBounds &bobo)
Assignment operator.
Definition: CombinedVolumeBounds.cxx:61
RectangleBounds.h
Trk::SimplePolygonBrepVolumeBounds
Definition: SimplePolygonBrepVolumeBounds.h:44
Surface.h
Trk::SubtractedCylinderSurface
Definition: SubtractedCylinderSurface.h:33
CaloCondBlobAlgs_fillNoiseFromASCII.db
db
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:42
python.AthDsoLogger.out
out
Definition: AthDsoLogger.py:70
Trk::CombinedVolumeBounds::m_intersection
bool m_intersection
Definition: CombinedVolumeBounds.h:103
Trk::DiscSurface
Definition: DiscSurface.h:54
intersection
std::vector< std::string > intersection(std::vector< std::string > &v1, std::vector< std::string > &v2)
Definition: compareFlatTrees.cxx:25
Trk::CombinedVolumeBounds::boundsOrientation
const std::vector< bool > & boundsOrientation() const
This method returns bounds orientation.
Definition: CombinedVolumeBounds.h:136
Trk::CombinedVolumeBounds::m_second
std::unique_ptr< Volume > m_second
Definition: CombinedVolumeBounds.h:102
VolumeExcluder.h
Trk::VolumeBounds
Definition: VolumeBounds.h:45
CylinderVolumeBounds.h
SubtractedPlaneSurface.h
Trk::SubtractedPlaneSurface
Definition: SubtractedPlaneSurface.h:32
Trk::CombinedVolumeBounds::~CombinedVolumeBounds
virtual ~CombinedVolumeBounds()
Destructor.
Trk::CombinedVolumeBounds::dump
virtual MsgStream & dump(MsgStream &sl) const override final
Output Method for MsgStream.
Definition: CombinedVolumeBounds.cxx:315
MuonR4::inverse
CalibratedSpacePoint::Covariance_t inverse(const CalibratedSpacePoint::Covariance_t &mat)
Inverts the parsed matrix.
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonSpacePoint/src/UtilFunctions.cxx:65
Trk::CylinderSurface
Definition: CylinderSurface.h:55
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
Trk::DiscSurface::bounds
const SurfaceBounds & bounds() const override final
This method returns the bounds by reference.
Amg::transform
Amg::Vector3D transform(Amg::Vector3D &v, Amg::Transform3D &tr)
Transform a point from a Trasformation3D.
Definition: GeoPrimitivesHelpers.h:156
CylinderSurface.h
SubtractedCylinderSurface.h
Trk::AreaExcluder
Definition: AreaExcluder.h:26
Trk::CombinedVolumeBounds::m_objectAccessor
EightObjectsAccessor m_objectAccessor
Definition: CombinedVolumeBounds.h:104
Trk::CombinedVolumeBounds::CombinedVolumeBounds
CombinedVolumeBounds()
Default Constructor.
Trk::CylinderVolumeBounds
Definition: CylinderVolumeBounds.h:70
Trk::SubtractedPlaneSurface::shared
bool shared() const
This method indicates the subtraction mode.
SimplePolygonBrepVolumeBounds.h
Trk::SubtractedCylinderSurface::subtractedVolume
const AreaExcluder * subtractedVolume() const
This method allows access to the subtracted part.
Trk::VolumeExcluder::volume
const Volume * volume() const
Acces the subtracted volume.
Definition: VolumeExcluder.h:68
Trk::PlaneSurface
Definition: PlaneSurface.h:64
PlaneSurface.h
Trk::SubtractedVolumeBounds
Definition: SubtractedVolumeBounds.h:40
CombinedVolumeBounds.h
Trk::SubtractedVolumeBounds::decomposeToSurfaces
virtual std::vector< std::unique_ptr< Trk::Surface > > decomposeToSurfaces(const Amg::Transform3D &transform) override final
Method to decompose the Bounds into boundarySurfaces.
Definition: SubtractedVolumeBounds.cxx:67
DiscSurface.h
Trk::VolumeExcluder
Definition: VolumeExcluder.h:30
Trk::CombinedVolumeBounds::decomposeToSurfaces
virtual std::vector< std::unique_ptr< Trk::Surface > > decomposeToSurfaces(const Amg::Transform3D &transform) override final
Method to decompose the Bounds into boundarySurfaces.
Definition: CombinedVolumeBounds.cxx:74
Trk::CombinedVolumeBounds::m_first
std::unique_ptr< Volume > m_first
Definition: CombinedVolumeBounds.h:101
Trk::CombinedVolumeBounds
Definition: CombinedVolumeBounds.h:44
Trk::Volume
Definition: Volume.h:36
Trk::Surface::transform
const Amg::Transform3D & transform() const
Returns HepGeom::Transform3D by reference.
Trk::DiscBounds
Definition: DiscBounds.h:44
SubtractedVolumeBounds.h