ATLAS Offline Software
TrackingVolume.icc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 namespace Trk {
6 
7 inline const std::string&
8 TrackingVolume::volumeName() const
9 {
10  return m_name;
11 }
12 
13 inline unsigned int
14 TrackingVolume::layerAttempts(BoundarySurfaceFace exitFace) const
15 {
16  if (m_layerAttemptsCalculator)
17  return m_layerAttemptsCalculator->layerAttempts(exitFace);
18  return TRKGEOMETRY_MAXLAYERATTEMPTS;
19 }
20 
21 inline unsigned int
22 TrackingVolume::maxLayerAttempts() const
23 {
24  if (m_layerAttemptsCalculator)
25  return m_layerAttemptsCalculator->maxLayerAttempts();
26  return TRKGEOMETRY_MAXLAYERATTEMPTS;
27 }
28 
29 inline const LayerArray*
30 TrackingVolume::confinedLayers() const
31 {
32  return m_confinedLayers;
33 }
34 
35 inline LayerArray*
36 TrackingVolume::confinedLayers()
37 {
38  return m_confinedLayers;
39 }
40 
41 inline const TrackingVolumeArray*
42 TrackingVolume::confinedVolumes() const
43 {
44  return m_confinedVolumes;
45 }
46 
47 inline TrackingVolumeArray*
48 TrackingVolume::confinedVolumes()
49 {
50  return m_confinedVolumes;
51 }
52 
53 inline ArraySpan<Layer const* const>
54 TrackingVolume::confinedArbitraryLayers() const
55 {
56  if (m_confinedArbitraryLayers) {
57  return ArraySpan<Layer const* const>(&*m_confinedArbitraryLayers->begin(),
58  &*m_confinedArbitraryLayers->end());
59  }
60  return {};
61 }
62 
63 inline ArraySpan<Layer* const>
64 TrackingVolume::confinedArbitraryLayers()
65 {
66 
67  if (m_confinedArbitraryLayers) {
68  return ArraySpan<Layer* const>(&*m_confinedArbitraryLayers->begin(),
69  &*m_confinedArbitraryLayers->end());
70  }
71  return {};
72 }
73 
74 inline ArraySpan<DetachedTrackingVolume const * const>
75 TrackingVolume::confinedDetachedVolumes() const
76 {
77  if (m_confinedDetachedVolumes) {
78  return ArraySpan<DetachedTrackingVolume const* const>(
79  &*m_confinedDetachedVolumes->begin(), &*m_confinedDetachedVolumes->end());
80  }
81  return {};
82 }
83 
84 inline ArraySpan<DetachedTrackingVolume* const>
85 TrackingVolume::confinedDetachedVolumes()
86 {
87  if (m_confinedDetachedVolumes) {
88  return ArraySpan<DetachedTrackingVolume* const>(
89  &*m_confinedDetachedVolumes->begin(), &*m_confinedDetachedVolumes->end());
90  }
91  return {};
92 }
93 
94 inline ArraySpan<TrackingVolume const* const>
95 TrackingVolume::confinedDenseVolumes() const
96 {
97  if (m_confinedDenseVolumes) {
98  return ArraySpan<TrackingVolume const* const>(
99  &*m_confinedDenseVolumes->begin(), &*m_confinedDenseVolumes->end());
100  }
101  return {};
102 }
103 
104 inline ArraySpan<Trk::TrackingVolume* const>
105 TrackingVolume::confinedDenseVolumes()
106 {
107  if (m_confinedDenseVolumes) {
108  return ArraySpan<TrackingVolume* const>(&*m_confinedDenseVolumes->begin(),
109  &*m_confinedDenseVolumes->end());
110  }
111  return {};
112 }
113 
114 template<class T>
115 bool
116 TrackingVolume::onVolumeBoundary(const T& pars) const
117 {
118  // get the associated Surface
119  const Surface* pSurface = &pars.associatedSurface();
120  const auto& bSurfaces = boundarySurfaces();
121  // fast loop pointer comparison of the surfaces
122  for (size_t i = 0; i < bSurfaces.size(); ++i) {
123  const BoundarySurface<TrackingVolume>* bSurface = bSurfaces[i];
124  // pointer of the parameter surface is identical with one of the boundary
125  // surface pointers
126  if (pSurface == &bSurface->surfaceRepresentation())
127  return true;
128  }
129  // slow loop - checking the onSurface (does pointer comparison as well)
130  for (size_t i = 0; i < bSurfaces.size(); ++i) {
131  const BoundarySurface<TrackingVolume>* bSurface = bSurfaces[i];
132  // pointer of the parameter surface is identical with one of the boundary
133  // surface pointers
134  if (bSurface->onBoundary(pars))
135  return true;
136  }
137  // could not find an onSurface
138  return false;
139 }
140 
141 /** Return the material layers ordered based on straight line intersections
142  - start and end layer are always part of it
143 */
144 template<class T>
145 std::vector<LayerIntersection<T>>
146 TrackingVolume::materialLayersOrdered(const Layer* sLayer,
147  const Layer* eLayer,
148  const T& pars,
149  PropDirection pDir,
150  const BoundaryCheck& bchk,
151  bool resolveSubSurfaces) const
152 {
153  // get position and momentum from the parameters
154  const Amg::Vector3D& gp = pars.position();
155  const Amg::Vector3D& gm = pars.momentum();
156  // the layer intersections
157  std::vector<LayerIntersection<T>> lIntersections;
158  // assign the direction
159  const Amg::Vector3D& dir =
160  (pDir == alongMomentum ? gm.unit() : Amg::Vector3D(-1 * gm.unit()));
161  // the confinedLayers
162  if (m_confinedLayers) {
163  // cache the longest path length to avoid punch-through to the other side
164  Trk::Intersection sLayerIntersection(
165  Amg::Vector3D(0., 0., 0), 0., true, 0.);
166  const Trk::Surface* sLayerSurface = nullptr;
167  double validPathLength = 0.;
168  // start layer given or not - test layer
169  const Trk::Layer* tLayer = sLayer ? sLayer : associatedLayer(gp);
170  if (tLayer) {
171  do {
172  // collect material or sensitive layers, always provide the final layer
173  // for the navigation stop
174  if (tLayer->layerMaterialProperties() || tLayer->surfaceArray() ||
175  tLayer == eLayer) {
176  // get the approaching surface
177  const Surface& tSurface =
178  tLayer->surfaceOnApproach(gp, dir, pDir, bchk, resolveSubSurfaces);
179  // calculate the intersection with the layer
180  Trk::Intersection lIntersection =
181  tSurface.straightLineIntersection(gp, dir, true, bchk);
182  // (a) if the current layer is NOT the start layer - intersection is
183  // ok
184  if (tLayer != sLayer && lIntersection.valid) {
185  lIntersections.push_back(
186  LayerIntersection<T>(lIntersection, tLayer, &tSurface, 0, pDir));
187  validPathLength = lIntersection.pathLength;
188  } else if (tLayer == sLayer) {
189  // (b) the current layer is the start layer - we need to cache it
190  // and check with the path length
191  // this avoids potential punch-through to other side of
192  sLayerIntersection = lIntersection;
193  sLayerSurface = &tSurface;
194  } else if (tLayer == eLayer) {
195  // (c) it is the end layer after all - provide it and break the loop
196  lIntersections.push_back(
197  LayerIntersection<T>(lIntersection, tLayer, &tSurface, 0, pDir));
198  break;
199  }
200  }
201  // move to next one or break because you reached the end layer
202  tLayer = (tLayer == eLayer) ? nullptr : tLayer->nextLayer(gp, dir);
203  } while (tLayer);
204  }
205 
206  // final check for compatibility of the start layer in order to avoid
207  // punch-through
208  if (sLayer && sLayerIntersection.valid &&
209  sLayerIntersection.pathLength < validPathLength)
210  lIntersections.push_back(LayerIntersection<T>(
211  sLayerIntersection, sLayer, sLayerSurface, 0, pDir));
212  }
213  // and the arbitraray layers
214  if (m_confinedArbitraryLayers) {
215  // loop over the layers and intersect them
216  for (auto& layer : (*m_confinedArbitraryLayers)) {
217  // intersections
218  Trk::Intersection lIntersection =
219  layer->surfaceRepresentation().straightLineIntersection(
220  gp, dir, true, bchk);
221  if (lIntersection.valid)
222  lIntersections.push_back(LayerIntersection<T>(
223  lIntersection, layer, &(layer->surfaceRepresentation()), 0, pDir));
224  }
225  }
226 
227  // sort them accordingly to the path length
228  std::sort(lIntersections.begin(), lIntersections.end());
229  // and return
230  return lIntersections;
231 }
232 
233 /** Returns the boundary surfaces ordered in probability to hit them based on
234  * straight line intersection @todo change hard-coded default */
235 template<class T>
236 std::vector<BoundaryIntersection<T>>
237 TrackingVolume::boundarySurfacesOrdered(const T& pars,
238  PropDirection pDir,
239  bool) const
240 {
241 
242  // assign the direction
243 
244  const Amg::Vector3D dir =
245  (pDir == alongMomentum ? pars.momentum().unit()
246  : Amg::Vector3D(-1 * pars.momentum().unit()));
247  // loop over boundarySurfaces and calculate the intersection
248  std::vector<BoundaryIntersection<T>> bIntersections;
249  const auto& bSurfaces = boundarySurfaces();
250  for (size_t i = 0; i < bSurfaces.size(); ++i) {
251  const BoundarySurface<TrackingVolume>* bSurface = bSurfaces[i];
252  Intersection bsIntersection =
253  bSurface->surfaceRepresentation().straightLineIntersection(
254  pars.position(), dir, true, false);
255  if (bsIntersection.valid)
256  bIntersections.push_back(
257  BoundaryIntersection<T>(bsIntersection,
258  bSurface,
259  &(bSurface->surfaceRepresentation()),
260  0,
261  pDir));
262  }
263  // and now sort to get the closest
264  std::sort(bIntersections.begin(), bIntersections.end());
265  // and return
266  return bIntersections;
267 }
268 
269 inline GeometrySignature
270 TrackingVolume::geometrySignature() const
271 {
272  return m_geometrySignature;
273 }
274 
275 inline GeometryType
276 TrackingVolume::geometryType() const
277 {
278  return m_geometryType;
279 }
280 
281 inline void
282 TrackingVolume::registerColorCode(unsigned int icolor)
283 {
284  m_colorCode = icolor;
285 }
286 
287 inline unsigned int
288 TrackingVolume::colorCode() const
289 {
290  return m_colorCode;
291 }
292 
293 inline void
294 TrackingVolume::forceNavigationCheck()
295 {
296  m_redoNavigation = true;
297 }
298 
299 inline bool
300 TrackingVolume::redoNavigation() const
301 {
302  return m_redoNavigation;
303 }
304 
305 inline const TrackingVolume*
306 TrackingVolume::getMotherVolume() const
307 {
308  return m_motherVolume;
309 }
310 
311 inline void
312 TrackingVolume::setMotherVolume(const TrackingVolume* mvol)
313 {
314  m_motherVolume = mvol;
315 }
316 
317 inline bool
318 TrackingVolume::isAlignable() const
319 {
320  return false;
321 }
322 
323 }