ATLAS Offline Software
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
18 #include "TrkSurfaces/DiscBounds.h"
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 
35 Trk::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))
39  , m_objectAccessor()
40  , m_boundsOrientation()
41 {}
42 
44  const Trk::SubtractedVolumeBounds& bobo)
45  : VolumeBounds()
46  , m_outer{bobo.m_outer->clone()}
47  , m_inner{bobo.m_inner->clone()}
48  , m_objectAccessor(bobo.m_objectAccessor)
49  , m_boundsOrientation(bobo.m_boundsOrientation)
50 {}
51 
53 
56 {
57  if (this != &bobo) {
58  m_outer.reset(bobo.m_outer->clone());
59  m_inner.reset(bobo.m_inner->clone());
60  m_objectAccessor = bobo.m_objectAccessor;
61  m_boundsOrientation = bobo.m_boundsOrientation;
62  }
63  return *this;
64 }
65 
66 std::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 
280 MsgStream&
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 
293 std::ostream&
294 Trk::SubtractedVolumeBounds::dump(std::ostream& sl) const
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 
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::SubtractedVolumeBounds::boundsOrientation
const std::vector< bool > & boundsOrientation() const
This method returns bounds orientation.
Definition: SubtractedVolumeBounds.h:122
DiscBounds.h
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
Trk::SubtractedVolumeBounds::dump
MsgStream & dump(MsgStream &sl) const override
Output Method for MsgStream.
Definition: SubtractedVolumeBounds.cxx:281
python.AthDsoLogger.out
out
Definition: AthDsoLogger.py:70
Trk::DiscSurface
Definition: DiscSurface.h:54
Trk::CombinedVolumeBounds::boundsOrientation
const std::vector< bool > & boundsOrientation() const
This method returns bounds orientation.
Definition: CombinedVolumeBounds.h:136
VolumeExcluder.h
Trk::VolumeBounds
Definition: VolumeBounds.h:45
CylinderVolumeBounds.h
Volume.h
Trk::SubtractedVolumeBounds::createSubtractedVolume
static Trk::Volume * createSubtractedVolume(const Amg::Transform3D &transf, Trk::Volume *subtrVol)
Definition: SubtractedVolumeBounds.cxx:307
SubtractedPlaneSurface.h
Trk::SubtractedPlaneSurface
Definition: SubtractedPlaneSurface.h:32
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
Trk::SubtractedVolumeBounds::operator=
SubtractedVolumeBounds & operator=(const SubtractedVolumeBounds &bobo)
Assignment operator.
Definition: SubtractedVolumeBounds.cxx:55
SubtractedCylinderSurface.h
Trk::AreaExcluder
Definition: AreaExcluder.h:26
Trk::CylinderVolumeBounds
Definition: CylinderVolumeBounds.h:70
Trk::SubtractedPlaneSurface::shared
bool shared() const
This method indicates the subtraction mode.
Trk::SubtractedVolumeBounds::m_inner
std::unique_ptr< Volume > m_inner
Definition: SubtractedVolumeBounds.h:95
SimplePolygonBrepVolumeBounds.h
Trk::SubtractedVolumeBounds::m_outer
std::unique_ptr< Volume > m_outer
Definition: SubtractedVolumeBounds.h:94
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
Trk::SubtractedVolumeBounds::m_objectAccessor
EightObjectsAccessor m_objectAccessor
There's only one single object Acessor for the moment has to be implemented if Subtracteds are used m...
Definition: SubtractedVolumeBounds.h:98
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::SubtractedVolumeBounds::SubtractedVolumeBounds
SubtractedVolumeBounds()
Default Constructor.
Trk::SubtractedVolumeBounds::~SubtractedVolumeBounds
virtual ~SubtractedVolumeBounds()
Destructor.
Trk::SubtractedVolumeBounds::m_boundsOrientation
std::vector< bool > m_boundsOrientation
Definition: SubtractedVolumeBounds.h:99
Trk::VolumeExcluder
Definition: VolumeExcluder.h:30
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