ATLAS Offline Software
Layer.icc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 namespace Trk {
6 
7 inline const SurfaceArray *Layer::surfaceArray() const {
8  return m_surfaceArray.get();
9 }
10 
11 inline SurfaceArray *Layer::surfaceArray(){
12  return m_surfaceArray.get();
13 }
14 
15 inline double Layer::thickness() const { return m_layerThickness; }
16 
17 template <class T>
18 bool Layer::onLayer(const T &pars, const BoundaryCheck &bcheck) const {
19  // simple check first .. compare surfaces if parameters are AtaSurface
20  if (pars.type() == AtaSurface) {
21  // surface based association
22  if (&pars.associatedSurface() == &surfaceRepresentation())
23  return (bcheck ? surfaceRepresentation().insideBoundsCheck(
24  pars.localPosition(), bcheck)
25  : true);
26  // layer based association
27  if ((pars.associatedSurface().associatedLayer() == this) && !bcheck)
28  return true;
29  }
30  return isOnLayer(pars.position(), bcheck);
31 }
32 
33 /** returns all Compatible surfaces with given BoundaryCheck */
34 template <class T>
35 size_t Layer::getCompatibleSurfaces(std::vector<SurfaceIntersection> &cSurfaces,
36  const T &pars, PropDirection pDir,
37  const BoundaryCheck &bcheck,
38  bool materialSurfacesOnly,
39  const Surface *startSurface,
40  const Surface *endSurface,
41  const ICompatibilityEstimator *) const {
42  // fast exit - nothing to do
43  if (!m_surfaceArray || !m_overlapDescriptor)
44  return 0;
45 
46  // position and momentum/dir
47  const Amg::Vector3D &pos = pars.position();
48  const Amg::Vector3D dir = (pDir == oppositeMomentum)
49  ? Amg::Vector3D(-1. * pars.momentum().unit())
50  : pars.momentum().unit();
51 
52  // check if you need to force the momentum direction
53  const bool fDirection = (pDir != anyDirection);
54 
55  // check if you have to stop at the endSurface
56  double maxPathLength = 10e10;
57  if (endSurface) {
58  // intersect the end surface
59  Intersection endInter =
60  endSurface->straightLineIntersection(pos, dir, fDirection, bcheck);
61  // non-valid intersection with the end surface provided at this layer
62  // indicates wrong direction or faulty setup
63  // -> do not return compatible surfaces since they may lead you on a wrong
64  // navigation path
65  if (endInter.valid && endInter.pathLength > 0.) {
66  maxPathLength = endInter.pathLength;
67  } else {
68  return 0;
69  }
70  }
71 
72  // create a for loop for the moment because there are two different modes:
73  // - the layer does the intersection already
74  // - you do the intersection
75  // get the main target surface
76  const Surface *tSurface = subSurface(pos);
77  // clear the vector, just in case
78  cSurfaces.clear();
79  if (!tSurface) {
80  return 0;
81  }
82  // get the reachable surfaces, the target surface will be added
83  std::vector<SurfaceIntersection> testSurfaces;
84  const bool acceptSurfaces =
85  m_overlapDescriptor->reachableSurfaces(testSurfaces, *tSurface, pos, dir);
86 
87  if (acceptSurfaces) {
88  if (!startSurface && !endSurface && !materialSurfacesOnly) {
89  // no start nor end surface is given - accept totally if not configured to
90  // only collect material surfaces
91  cSurfaces = std::move(testSurfaces);
92  } else {
93  cSurfaces.reserve(testSurfaces.size());
94  // endSurface was given - check for maxPathLength && endSurface
95  for (const auto &tSurface : testSurfaces) {
96  // exclude the startSurface and endSurface from this loop
97  if (tSurface.object == endSurface || tSurface.object == startSurface) {
98  continue;
99  }
100  // accept if in path range
101  if (tSurface.intersection.pathLength < maxPathLength &&
102  (!materialSurfacesOnly || tSurface.object->materialLayer()))
103  cSurfaces.push_back(tSurface);
104  }
105  }
106  } else if (!testSurfaces.empty()) {
107  cSurfaces.reserve(testSurfaces.size());
108  for (const auto &tSurface : testSurfaces) {
109  // exclude the endSurface
110  if (tSurface.object == endSurface || tSurface.object == startSurface){
111  continue;
112  }
113  // minimize the computational cost
114  Intersection tsfInter = tSurface.object->straightLineIntersection(
115  pos, dir, fDirection, false);
116  // check if the intersection is valid and the maxPathLength has not been
117  // exceeded
118  if (tsfInter.valid && tsfInter.pathLength < maxPathLength) {
119  // resulting propDirection
120  PropDirection rDir =
121  fDirection
122  ? pDir
123  : (tsfInter.pathLength > 0 ? alongMomentum : oppositeMomentum);
124  // and the surfaces & direction to push back - take only material
125  // surfaces if configured to do so
126  if (!materialSurfacesOnly || tSurface.object->materialLayer())
127  cSurfaces.emplace_back(tsfInter, tSurface.object, rDir);
128  }
129  }
130  }
131  // the layer surface itself is a testSurface - if there's material
132  const Surface *layerSurface = &surfaceRepresentation();
133  if (layerMaterialProperties() && layerSurface != startSurface &&
134  layerSurface != endSurface) {
135  // self intersection
136  Intersection lInter = surfaceRepresentation().straightLineIntersection(
137  pos, dir, fDirection, bcheck);
138  // allow only if it is in the maximal path length
139  if (lInter.valid && lInter.pathLength < maxPathLength)
140  cSurfaces.emplace_back(lInter, layerSurface, pDir);
141  }
142  // now sort it
143  std::sort(cSurfaces.begin(), cSurfaces.end());
144  // return
145  return cSurfaces.size();
146 }
147 
148 inline const LayerMaterialProperties *Layer::layerMaterialProperties() const {
149  return m_layerMaterialProperties.get();
150 }
151 
152 inline const OverlapDescriptor *Layer::overlapDescriptor() const {
153  return m_overlapDescriptor.get();
154 }
155 /** set the previous Layer*/
156 inline void Layer::setPreviousLayer(const Layer *in) { m_previousLayer = in; }
157 
158 /** set the next Layer*/
159 inline void Layer::setNextLayer(const Layer *in) { m_nextLayer = in; }
160 
161 /** access the BinUtility*/
162 inline const BinUtility *Layer::binUtility() const { return m_binUtility; }
163 /** set the BinUtility*/
164 inline void Layer::setBinUtility(const BinUtility *in) { m_binUtility = in; }
165 
166 inline const TrackingVolume *Layer::enclosingTrackingVolume() const {
167  return m_enclosingTrackingVolume;
168 }
169 inline void Layer::encloseTrackingVolume(const TrackingVolume &tvol) {
170  m_enclosingTrackingVolume = &(tvol);
171 }
172 
173 inline const DetachedTrackingVolume *
174 Layer::enclosingDetachedTrackingVolume() const {
175  return m_enclosingDetachedTrackingVolume;
176 }
177 inline void
178 Layer::encloseDetachedTrackingVolume(const DetachedTrackingVolume &tvol) {
179  m_enclosingDetachedTrackingVolume = &(tvol);
180 }
181 
182 inline const LayerIndex &Layer::layerIndex() const { return m_index; }
183 
184 inline int Layer::layerType() const { return m_layerType; }
185 inline void Layer::setLayerType(int id) { m_layerType = id; }
186 
187 inline void Layer::registerLayerIndex(const LayerIndex &lIdx) {
188  m_index = lIdx;
189 }
190 
191 inline double Layer::getRef() const { return m_ref; }
192 inline void Layer::setRef(double x) { m_ref = x; }
193 
194 } // namespace Trk