ATLAS Offline Software
PrismVolumeBounds.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 // PrismVolumeBounds.cxx, (c) ATLAS Detector software
8 
9 // Trk
11 #include "TrkVolumes/Volume.h"
12 // TrkSurfaces
16 // Gaudi
17 #include "GaudiKernel/MsgStream.h"
18 #include "GaudiKernel/SystemOfUnits.h"
19 // STD
20 #include <cmath>
21 #include <iomanip>
22 #include <iostream>
23 
25  : VolumeBounds()
26  , m_halfZ()
27  , m_baseBounds(nullptr)
28  , m_ordering()
29  , // invalid cache
30  m_objectAccessor()
31 {}
32 
34  std::vector<std::pair<float, float>> xyVtx,
35  float halez)
36  : VolumeBounds()
37  , m_halfZ(halez)
38  , m_baseBounds(nullptr)
39  , m_ordering()
40  , // invalid cache
41  m_objectAccessor()
42 {
43  m_xyVtx.resize(xyVtx.size());
44  m_xyVtx.assign(xyVtx.begin(), xyVtx.end());
46 }
47 
49  std::vector<std::pair<double, double>> xyVtx,
50  double halez)
51  : VolumeBounds()
52  , m_halfZ(halez)
53  , m_baseBounds(nullptr)
54  , m_ordering()
55  , // invalid cache
56  m_objectAccessor()
57 {
58  m_xyVtx.resize(xyVtx.size());
59  m_xyVtx.assign(xyVtx.begin(), xyVtx.end());
61 }
62 
64  : VolumeBounds()
65  , m_halfZ(trabo.m_halfZ)
66  , m_baseBounds(nullptr)
67  , m_ordering(trabo.m_ordering)
68  , // ordering cache will be valid if trabo/other cache is valid
69  m_objectAccessor(trabo.m_objectAccessor)
70 {
71  m_xyVtx.resize(trabo.m_xyVtx.size());
72  m_xyVtx.assign(trabo.m_xyVtx.begin(), trabo.m_xyVtx.end());
74 }
75 
77 {
78  delete m_baseBounds;
79 }
80 
83 {
84  if (this != &trabo) {
85  m_halfZ = trabo.m_halfZ;
86  m_objectAccessor = trabo.m_objectAccessor;
87  m_xyVtx.resize(trabo.m_xyVtx.size());
88  m_xyVtx.assign(trabo.m_xyVtx.begin(), trabo.m_xyVtx.end());
89  delete m_baseBounds;
90  m_baseBounds = new Trk::TriangleBounds(m_xyVtx);
91  m_ordering =
92  trabo.m_ordering; // ordering cache will be valid if trabo cache is valid
93  }
94  return *this;
95 }
96 
97 std::vector<std::unique_ptr<Trk::Surface>>
100 {
101  auto retsf = std::vector<std::unique_ptr<Trk::Surface>>();
102 
103  // face surfaces xy
104  // (1) - at positive local z
105  auto xyPlane = std::make_unique<Trk::PlaneSurface>(
107  transform * Amg::Translation3D(Amg::Vector3D(0., 0., m_halfZ))),
108  std::make_shared<Trk::TriangleBounds>(m_xyVtx));
109  retsf.push_back(std::move(xyPlane));
110  // (2) - at negative local z
111  auto xymPlane = std::make_unique<Trk::PlaneSurface>(
113  transform * Amg::Translation3D(Amg::Vector3D(0., 0., -m_halfZ)) *
114  Amg::AngleAxis3D(180 * Gaudi::Units::deg, Amg::Vector3D(1., 0., 0.))),
115  std::make_shared<Trk::TriangleBounds>(mirror_xyVtx()));
116  retsf.push_back(std::move(xymPlane));
117  // loop over xy vertices
118  // (3)
119  for (unsigned int iv = 0; iv < m_xyVtx.size(); iv++) {
120  if (iv != m_xyVtx.size() - 1)
121  retsf.push_back(sideSurf(transform, iv, iv + 1));
122  else
123  retsf.push_back(sideSurf(transform, iv, 0));
124  }
125 
126  return retsf;
127 }
128 
129 // faces in xy
130 std::unique_ptr<Trk::PlaneSurface>
133  unsigned int iv1,
134  unsigned int iv2) const
135 {
136  std::unique_ptr<Trk::PlaneSurface> plane = nullptr;
137 
138  double xdif = m_xyVtx[iv2].first - m_xyVtx[iv1].first;
139  double ydif = m_xyVtx[iv2].second - m_xyVtx[iv1].second;
140  double xsize = sqrt(xdif * xdif + ydif * ydif);
141 
142  double ori = ordering() > 0 ? 1. : -1.;
143 
145  0.5 * (m_xyVtx[iv1].first + m_xyVtx[iv2].first),
146  0.5 * (m_xyVtx[iv1].second + m_xyVtx[iv2].second),
147  0.);
148  double phi = ori * ydif < 0 ? M_PI / 2 : -M_PI / 2;
149  if (ori > 0 && ydif > 0)
150  phi = M_PI / 2;
151  if (std::abs(xdif) > 1e-6) {
152  phi = atan(ydif / xdif);
153  if (xdif < 0)
154  phi += M_PI;
155  }
156 
157  Amg::Transform3D tr(
159  Amg::AngleAxis3D(phi, Amg::Vector3D(0., 0., 1.)) *
160  Amg::AngleAxis3D(-ori * 90 * Gaudi::Units::deg, Amg::Vector3D(1., 0., 0.)));
161  plane = std::make_unique<Trk::PlaneSurface>(tr, std::make_shared<Trk::RectangleBounds>(0.5 * xsize, m_halfZ));
162 
163  // verify position of vertices - uncomment for debugging
164  // if
165  // (!plane->isOnSurface(Trk::GlobalPosition(m_xyVtx[iv1].first,m_xyVtx[iv1].second,m_halfZ),true,0.001,0.001)
166  // ||
167  // !plane->isOnSurface(Trk::GlobalPosition(m_xyVtx[iv2].first,m_xyVtx[iv2].second,-m_halfZ),true,0.001,0.001)
168  // )
169  // std::cout << "ERROR in PRISM side boundary:vertices out of plane"<<
170  // std::endl;
171 
172  // orientation
173  int ivr = (iv1 == 0 || iv2 == 0) ? 1 : 0;
174  if (ivr == 1 && (iv1 == 1 || iv2 == 1))
175  ivr = 2;
176 
177  double ox = m_xyVtx[ivr].first - pos[0];
178  double oy = m_xyVtx[ivr].second - pos[1];
179  Amg::Vector3D d(ox, oy, 0.);
180 
181  // protect against wrong orientation
182  if (d.dot(plane->normal()) > 0.) {
183  tr = Amg::Transform3D(
185  Amg::AngleAxis3D(phi + M_PI, Amg::Vector3D(0., 0., 1.)) *
187  -ori * 90 * Gaudi::Units::deg, Amg::Vector3D(1., 0., 0.)));
188  plane =
189  std::make_unique<Trk::PlaneSurface>(tr, std::make_shared<Trk::RectangleBounds>(0.5 * xsize, m_halfZ));
190  }
191 
192  return plane;
193 }
194 
195 bool
197 {
198  if (std::abs(pos.z()) > m_halfZ + tol)
199  return false;
200  // xy plane
201  Amg::Vector2D locp(pos.x(), pos.y());
202  return (m_baseBounds->inside(locp, tol, tol));
203 }
204 
205 std::vector<std::pair<double, double>>
207 {
208  std::vector<std::pair<double, double>> mirrored;
209  mirrored.resize(m_xyVtx.size());
210 
211  for (unsigned int i = 0; i < m_xyVtx.size(); i++)
212  mirrored[i] =
213  std::pair<double, double>(m_xyVtx[i].first, -m_xyVtx[i].second);
214 
215  return mirrored;
216 }
217 
218 int
220 {
221  if (m_ordering.isValid()) {
222  return *(m_ordering.ptr());
223  }
224 
225  int tmp_ordering = 1;
226 
227  double yd2 = m_xyVtx[2].second - m_xyVtx[1].second;
228  double yd0 = m_xyVtx[0].second - m_xyVtx[1].second;
229  double xd2 = m_xyVtx[2].first - m_xyVtx[1].first;
230  double xd0 = m_xyVtx[0].first - m_xyVtx[1].first;
231  double ph2 = yd2 < 0 ? -M_PI / 2 : M_PI / 2;
232  if (std::abs(xd2) > 1e-6) {
233  ph2 = atan(yd2 / xd2);
234  if (xd2 < 0)
235  ph2 += M_PI;
236  }
237  double ph0 = yd0 < 0 ? -M_PI / 2 : M_PI / 2;
238  if (std::abs(xd0) > 1e-6) {
239  ph0 = atan(yd0 / xd0);
240  if (xd0 < 0)
241  ph0 += M_PI;
242  }
243  if (ph0 < 0)
244  ph0 += 2 * M_PI;
245  if (ph2 < 0)
246  ph2 += 2 * M_PI;
247 
248  if ((ph0 > ph2 && ph0 - ph2 < M_PI) || (ph2 - ph0) > M_PI)
249  tmp_ordering = 0;
250 
251  m_ordering.set(tmp_ordering);
252  return *(m_ordering.ptr());
253 }
254 
255 // ostream operator overload
256 MsgStream&
257 Trk::PrismVolumeBounds::dump(MsgStream& sl) const
258 {
259  std::stringstream temp_sl;
260  temp_sl << std::setiosflags(std::ios::fixed);
261  temp_sl << std::setprecision(7);
262  temp_sl << "Trk::PrismVolumeBounds: (halfZ, generating vtx) = ";
263  temp_sl << "( " << m_halfZ << ")";
264  for (const auto & myVtx : m_xyVtx)
265  temp_sl << "(" << myVtx.first << "," << myVtx.second << ")";
266  sl << temp_sl.str();
267 
268  return sl;
269 }
270 
271 std::ostream&
272 Trk::PrismVolumeBounds::dump(std::ostream& sl) const
273 {
274  std::stringstream temp_sl;
275  temp_sl << std::setiosflags(std::ios::fixed);
276  temp_sl << std::setprecision(7);
277  temp_sl << "Trk::PrismVolumeBounds: (halfZ, generating vtx) = ";
278  temp_sl << "( " << m_halfZ << ")";
279  for (const auto & myVtx : m_xyVtx)
280  temp_sl << "(" << myVtx.first << "," << myVtx.second << ")";
281  sl << temp_sl.str();
282 
283  return sl;
284 }
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
Trk::PrismVolumeBounds::decomposeToSurfaces
virtual std::vector< std::unique_ptr< Trk::Surface > > decomposeToSurfaces(const Amg::Transform3D &transform) override final
Method to decompose the Bounds into Surfaces.
Definition: PrismVolumeBounds.cxx:99
Trk::PrismVolumeBounds::m_ordering
CxxUtils::CachedValue< int > m_ordering
cache vertex ordering
Definition: PrismVolumeBounds.h:108
RectangleBounds.h
Amg::Vector2D
Eigen::Matrix< double, 2, 1 > Vector2D
Definition: GeoPrimitives.h:48
hist_file_dump.d
d
Definition: hist_file_dump.py:142
python.SystemOfUnits.second
float second
Definition: SystemOfUnits.py:135
Trk::PrismVolumeBounds::m_objectAccessor
Trk::EightObjectsAccessor m_objectAccessor
There's only one single object Acessor for the moment has to be implemented if Cuboids are used more ...
Definition: PrismVolumeBounds.h:113
M_PI
#define M_PI
Definition: ActiveFraction.h:11
deg
#define deg
Definition: SbPolyhedron.cxx:17
Trk::PrismVolumeBounds::m_halfZ
double m_halfZ
halflength in z
Definition: PrismVolumeBounds.h:106
Trk::PrismVolumeBounds::sideSurf
std::unique_ptr< Trk::PlaneSurface > sideSurf(const Amg::Transform3D &, unsigned int, unsigned int) const
method to construct side boundary planes
Definition: PrismVolumeBounds.cxx:131
drawFromPickle.atan
atan
Definition: drawFromPickle.py:36
PrismVolumeBounds.h
Trk::VolumeBounds
Definition: VolumeBounds.h:46
Volume.h
Trk::TriangleBounds
Definition: TriangleBounds.h:39
lumiFormat.i
int i
Definition: lumiFormat.py:85
Trk::PrismVolumeBounds::PrismVolumeBounds
PrismVolumeBounds()
Default Constructor.
Definition: PrismVolumeBounds.cxx:24
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
Amg::transform
Amg::Vector3D transform(Amg::Vector3D &v, Amg::Transform3D &tr)
Transform a point from a Trasformation3D.
Definition: GeoPrimitivesHelpers.h:156
Trk::Surface::normal
virtual const Amg::Vector3D & normal() const
Returns the normal vector of the Surface (i.e.
Trk::PrismVolumeBounds
Definition: PrismVolumeBounds.h:44
Trk::PrismVolumeBounds::inside
bool inside(const Amg::Vector3D &, double tol=0.) const override final
This method checks if position in the 3D volume frame is inside the volume.
Definition: PrismVolumeBounds.cxx:196
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
Trk::PrismVolumeBounds::dump
MsgStream & dump(MsgStream &sl) const override final
Output Method for MsgStream.
Definition: PrismVolumeBounds.cxx:257
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:16
Trk::PrismVolumeBounds::operator=
PrismVolumeBounds & operator=(const PrismVolumeBounds &bobo)
Assignment operator.
Definition: PrismVolumeBounds.cxx:82
Trk::PrismVolumeBounds::~PrismVolumeBounds
virtual ~PrismVolumeBounds()
Destructor.
Definition: PrismVolumeBounds.cxx:76
TriangleBounds.h
Trk::PrismVolumeBounds::m_xyVtx
std::vector< std::pair< double, double > > m_xyVtx
generating xy vertices
Definition: PrismVolumeBounds.h:105
PlaneSurface.h
Trk::PrismVolumeBounds::mirror_xyVtx
std::vector< std::pair< double, double > > mirror_xyVtx() const
mirror the input vertices for down-side boundary
Definition: PrismVolumeBounds.cxx:206
DeMoScan.first
bool first
Definition: DeMoScan.py:534
Amg::Translation3D
Eigen::Translation< double, 3 > Translation3D
Definition: GeoPrimitives.h:44
Amg::AngleAxis3D
Eigen::AngleAxisd AngleAxis3D
Definition: GeoPrimitives.h:45
Trk::PrismVolumeBounds::ordering
int ordering() const
assess ordering of vertices
Definition: PrismVolumeBounds.cxx:219
Trk::phi
@ phi
Definition: ParamDefs.h:75
Trk::PrismVolumeBounds::m_baseBounds
Trk::TriangleBounds * m_baseBounds
base xy bounds
Definition: PrismVolumeBounds.h:107
hist_file_dump.ordering
ordering
Definition: hist_file_dump.py:85