Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CylinderVolumeBounds.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file CylinderVolumeBounds.hpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2016-2020 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
9 #pragma once
10 
12 #include "Acts/Geometry/Volume.hpp"
16 
17 #include <array>
18 #include <cmath>
19 #include <iomanip>
20 #include <iosfwd>
21 #include <memory>
22 #include <ostream>
23 #include <stdexcept>
24 #include <vector>
25 
26 namespace Acts {
27 
28 class CylinderBounds;
29 class RadialBounds;
30 class PlanarBounds;
31 
69 // Rectangular Acts::PlaneSurface attached to
73  public:
75  enum BoundValues : unsigned int {
76  eMinR = 0,
77  eMaxR = 1,
84  };
85 
86  CylinderVolumeBounds() = delete;
87 
97  CylinderVolumeBounds(double rmin, double rmax, double halfz,
98  double halfphi = M_PI, double avgphi = 0.,
99  double bevelMinZ = 0.,
100  double bevelMaxZ = 0.) noexcept(false)
101  : m_values({rmin, rmax, halfz, halfphi, avgphi, bevelMinZ, bevelMaxZ}) {
104  }
105 
109  CylinderVolumeBounds(const std::array<double, eSize>& values) noexcept(false)
110  : m_values(values) {
113  }
114 
119  CylinderVolumeBounds(const CylinderBounds& cBounds,
120  double thickness) noexcept(false);
121 
127  double thickness) noexcept(false);
128 
132  CylinderVolumeBounds(const CylinderVolumeBounds& cylbo) = default;
133 
134  ~CylinderVolumeBounds() override = default;
135  CylinderVolumeBounds& operator=(const CylinderVolumeBounds& cylbo) = default;
136 
139  }
140 
144  std::vector<double> values() const final;
145 
151  bool inside(const Vector3& pos, double tol = 0.) const override;
152 
164  const Transform3& transform = Transform3::Identity()) const override;
165 
171  Volume::BoundingBox boundingBox(const Transform3* trf = nullptr,
172  const Vector3& envelope = {0, 0, 0},
173  const Volume* entity = nullptr) const final;
174 
178  Vector3 binningOffset(BinningValue bValue) const override;
179 
183  double binningBorder(BinningValue bValue) const override;
184 
186  std::ostream& toStream(std::ostream& sl) const override;
187 
190  double get(BoundValues bValue) const { return m_values[bValue]; }
191 
192  private:
194  std::array<double, eSize> m_values{};
196  std::shared_ptr<const CylinderBounds> m_innerCylinderBounds{nullptr};
198  std::shared_ptr<const CylinderBounds> m_outerCylinderBounds{nullptr};
200  std::shared_ptr<const RadialBounds> m_discBounds{nullptr};
202  std::shared_ptr<const PlanarBounds> m_sectorPlaneBounds{nullptr};
203 
206  void checkConsistency() noexcept(false);
207 
209  void buildSurfaceBounds();
210 
214  template <class stream_t>
215  stream_t& dumpT(stream_t& dt) const;
216 };
217 
218 inline bool CylinderVolumeBounds::inside(const Vector3& pos, double tol) const {
219  using VectorHelpers::perp;
220  using VectorHelpers::phi;
221  double ros = perp(pos);
222  bool insidePhi = cos(phi(pos)) >= cos(get(eHalfPhiSector)) - tol;
223  bool insideR = insidePhi
224  ? ((ros >= get(eMinR) - tol) && (ros <= get(eMaxR) + tol))
225  : false;
226  bool insideZ =
227  insideR ? (std::abs(pos.z()) <= get(eHalfLengthZ) + tol) : false;
228  return (insideZ && insideR && insidePhi);
229 }
230 
232  const { // the medium radius is taken for r-type binning
233  if (bValue == Acts::binR || bValue == Acts::binRPhi) {
234  return Vector3(0.5 * (get(eMinR) + get(eMaxR)), 0., 0.);
235  }
236  return VolumeBounds::binningOffset(bValue);
237 }
238 
240  if (bValue == Acts::binR) {
241  return 0.5 * (get(eMaxR) - get(eMinR));
242  }
243  if (bValue == Acts::binZ) {
244  return get(eHalfLengthZ);
245  }
246  return VolumeBounds::binningBorder(bValue);
247 }
248 
249 template <class stream_t>
250 stream_t& CylinderVolumeBounds::dumpT(stream_t& dt) const {
251  dt << std::setiosflags(std::ios::fixed);
252  dt << std::setprecision(5);
253  dt << "Acts::CylinderVolumeBounds: (rMin, rMax, halfZ, halfPhi, "
254  "averagePhi, minBevelZ, maxBevelZ) = ";
255  dt << get(eMinR) << ", " << get(eMaxR) << ", " << get(eHalfLengthZ) << ", "
256  << get(eHalfPhiSector) << ", " << get(eAveragePhi) << ", "
257  << get(eBevelMinZ) << ", " << get(eBevelMaxZ);
258  return dt;
259 }
260 
261 inline std::vector<double> CylinderVolumeBounds::values() const {
262  std::vector<double> valvector;
263  valvector.insert(valvector.begin(), m_values.begin(), m_values.end());
264  return valvector;
265 }
266 
268  if (get(eMinR) < 0. or get(eMaxR) <= 0. or get(eMinR) >= get(eMaxR)) {
269  throw std::invalid_argument("CylinderVolumeBounds: invalid radial input.");
270  }
271  if (get(eHalfLengthZ) <= 0) {
272  throw std::invalid_argument(
273  "CylinderVolumeBounds: invalid longitudinal input.");
274  }
275  if (get(eHalfPhiSector) < 0. or get(eHalfPhiSector) > M_PI) {
276  throw std::invalid_argument(
277  "CylinderVolumeBounds: invalid phi sector setup.");
278  }
279  if (get(eAveragePhi) != detail::radian_sym(get(eAveragePhi))) {
280  throw std::invalid_argument(
281  "CylinderVolumeBounds: invalid phi positioning.");
282  }
283  if (get(eBevelMinZ) != detail::radian_sym(get(eBevelMinZ))) {
284  throw std::invalid_argument("CylinderBounds: invalid bevel at min Z.");
285  }
286  if (get(eBevelMaxZ) != detail::radian_sym(get(eBevelMaxZ))) {
287  throw std::invalid_argument("CylinderBounds: invalid bevel at max Z.");
288  }
289 }
290 
291 } // namespace Acts