ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
LayerArrayCreator.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file LayerArrayCreator.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2016-2018 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 
10 // LayerArrayCreator.cpp, Acts project
12 
14 #include <cmath>
17 #include "Acts/Geometry/Layer.hpp"
29 
30 std::unique_ptr<const Acts::LayerArray> Acts::LayerArrayCreator::layerArray(
31  const GeometryContext& gctx, const LayerVector& layersInput, double min,
32  double max, BinningType bType, BinningValue bValue) const {
33  ACTS_VERBOSE("Build LayerArray with " << layersInput.size()
34  << " layers at input.");
35  ACTS_VERBOSE(" min/max provided : " << min << " / " << max);
36  ACTS_VERBOSE(" binning type : " << bType);
37  ACTS_VERBOSE(" binning value : " << bValue);
38 
39  // create a local copy of the layer vector
40  LayerVector layers(layersInput);
41 
42  // sort it accordingly to the binning value
43  GeometryObjectSorterT<std::shared_ptr<const Layer>> layerSorter(gctx, bValue);
44  std::sort(layers.begin(), layers.end(), layerSorter);
45  // useful typedef
46  using LayerOrderPosition = std::pair<std::shared_ptr<const Layer>, Vector3D>;
47  // needed for all cases
48  std::shared_ptr<const Layer> layer = nullptr;
49  std::unique_ptr<const BinUtility> binUtility = nullptr;
50  std::vector<LayerOrderPosition> layerOrderVector;
51 
52  // switch the binning type
53  switch (bType) {
54  // equidistant binning - no navigation layers built - only equdistant layers
55  case equidistant: {
56  // loop over layers and put them in
57  for (auto& layIter : layers) {
58  ACTS_VERBOSE("equidistant : registering a Layer at binning position : "
59  << (layIter->binningPosition(gctx, bValue)));
60  layerOrderVector.push_back(LayerOrderPosition(
61  layIter, layIter->binningPosition(gctx, bValue)));
62  }
63  // create the binUitlity
64  binUtility = std::make_unique<const BinUtility>(layers.size(), min, max,
65  open, bValue);
66  ACTS_VERBOSE("equidistant : created a BinUtility as " << *binUtility);
67  } break;
68 
69  // arbitrary binning
70  case arbitrary: {
71  std::vector<float> boundaries;
72  // initial step
73  boundaries.push_back(min);
74  double layerValue = 0.;
75  double layerThickness = 0.;
76  std::shared_ptr<const Layer> navLayer = nullptr;
77  std::shared_ptr<const Layer> lastLayer = nullptr;
78  // loop over layers
79  for (auto& layIter : layers) {
80  // estimate the offset
81  layerThickness = layIter->thickness();
82  layerValue = layIter->binningPositionValue(gctx, bValue);
83  // register the new boundaries in the step vector
84  boundaries.push_back(layerValue - 0.5 * layerThickness);
85  boundaries.push_back(layerValue + 0.5 * layerThickness);
86  // calculate the layer value for the offset
87  double navigationValue = 0.5 * ((layerValue - 0.5 * layerThickness) +
88  boundaries.at(boundaries.size() - 3));
89  // if layers are attached to each other bail out - navigation will not
90  // work anymore
91  if (navigationValue == (layerValue - 0.5 * layerThickness)) {
92  ACTS_ERROR(
93  "Layers are attached to each other at: "
94  << layerValue - 0.5 * layerThickness
95  << ", which corrupts "
96  "navigation. This should never happen. Please detach the "
97  "layers in your geometry description.");
98  }
99  // if layers are overlapping bail out
100  if (navigationValue > (layerValue - 0.5 * layerThickness)) {
101  ACTS_ERROR("Layers are overlapping at: "
102  << layerValue - 0.5 * layerThickness
103  << ". This should never happen. "
104  "Please check your geometry description.");
105  }
106 
107  // create the navigation layer surface from the layer
108  std::shared_ptr<const Surface> navLayerSurface =
109  createNavigationSurface(gctx, *layIter, bValue,
110  -std::abs(layerValue - navigationValue));
111  ACTS_VERBOSE(
112  "arbitrary : creating a NavigationLayer at "
113  << (navLayerSurface->binningPosition(gctx, bValue)).x() << ", "
114  << (navLayerSurface->binningPosition(gctx, bValue)).y() << ", "
115  << (navLayerSurface->binningPosition(gctx, bValue)).z());
116  navLayer = NavigationLayer::create(std::move(navLayerSurface));
117  // push the navigation layer in
118  layerOrderVector.push_back(LayerOrderPosition(
119  navLayer, navLayer->binningPosition(gctx, bValue)));
120 
121  // push the original layer in
122  layerOrderVector.push_back(LayerOrderPosition(
123  layIter, layIter->binningPosition(gctx, bValue)));
124  ACTS_VERBOSE("arbitrary : registering MaterialLayer at "
125  << (layIter->binningPosition(gctx, bValue)).x() << ", "
126  << (layIter->binningPosition(gctx, bValue)).y() << ", "
127  << (layIter->binningPosition(gctx, bValue)).z());
128  // remember the last
129  lastLayer = layIter;
130  }
131  // a final navigation layer
132  // calculate the layer value for the offset
133  double navigationValue =
134  0.5 * (boundaries.at(boundaries.size() - 1) + max);
135  // create navigation layer only when necessary
136  if (navigationValue != max) {
137  // create the navigation layer surface from the layer
138  std::shared_ptr<const Surface> navLayerSurface =
139  createNavigationSurface(gctx, *lastLayer, bValue,
140  navigationValue - layerValue);
141  ACTS_VERBOSE(
142  "arbitrary : creating a NavigationLayer at "
143  << (navLayerSurface->binningPosition(gctx, bValue)).x() << ", "
144  << (navLayerSurface->binningPosition(gctx, bValue)).y() << ", "
145  << (navLayerSurface->binningPosition(gctx, bValue)).z());
146  navLayer = NavigationLayer::create(std::move(navLayerSurface));
147  // push the navigation layer in
148  layerOrderVector.push_back(LayerOrderPosition(
149  navLayer, navLayer->binningPosition(gctx, bValue)));
150  }
151  // now close the boundaries
152  boundaries.push_back(max);
153  // some screen output
154  ACTS_VERBOSE(layerOrderVector.size()
155  << " Layers (material + navigation) built. ");
156  // create the BinUtility
157  binUtility = std::make_unique<const BinUtility>(boundaries, open, bValue);
158  ACTS_VERBOSE("arbitrary : created a BinUtility as " << *binUtility);
159 
160  } break;
161  // default return nullptr
162  default: {
163  return nullptr;
164  }
165  }
166  // return the binned array
167  return std::make_unique<const BinnedArrayXD<LayerPtr>>(layerOrderVector,
168  std::move(binUtility));
169 }
170 
172  const GeometryContext& gctx, const Layer& layer, BinningValue bValue,
173  double offset) const {
174  // surface reference
175  const Surface& layerSurface = layer.surfaceRepresentation();
176  // translation to be applied
177  Vector3D translation(0., 0., 0.);
178  // switching he binnig values
179  switch (bValue) {
180  // case x
181  case binX: {
182  translation = Vector3D(offset, 0., 0.);
183  } break;
184  // case y
185  case binY: {
186  translation = Vector3D(0., offset, 0.);
187  } break;
188  // case z
189  case binZ: {
190  translation = Vector3D(0., 0., offset);
191  } break;
192  // case R
193  case binR: {
194  // binning in R and cylinder surface means something different
195  if (layerSurface.type() == Surface::Cylinder) {
196  break;
197  }
198  translation = Vector3D(offset, 0., 0.);
199  } break;
200  // do nothing for the default
201  default: {
202  ACTS_WARNING("Not yet implemented.");
203  }
204  }
205  // navigation surface
206  std::shared_ptr<Surface> navigationSurface;
207  // for everything else than a cylinder it's a copy with shift
208  if (layerSurface.type() == Surface::Plane) {
209  // create a transform that does the shift
210  Transform3D shift = Transform3D(Translation3D(translation));
211  const PlaneSurface* plane =
212  dynamic_cast<const PlaneSurface*>(&layerSurface);
213  navigationSurface = Surface::makeShared<PlaneSurface>(gctx, *plane, shift);
214  } else if (layerSurface.type() == Surface::Disc) {
215  // create a transform that does the shift
216  Transform3D shift = Transform3D(Translation3D(translation));
217  const DiscSurface* disc = dynamic_cast<const DiscSurface*>(&layerSurface);
218  navigationSurface = Surface::makeShared<DiscSurface>(gctx, *disc, shift);
219  } else if (layerSurface.type() == Surface::Cylinder) {
220  // get the bounds
221  const CylinderBounds* cBounds =
222  dynamic_cast<const CylinderBounds*>(&(layerSurface.bounds()));
223  double navigationR = cBounds->get(CylinderBounds::eR) + offset;
224  double halflengthZ = cBounds->get(CylinderBounds::eHalfLengthZ);
225  // create the new layer surface
226  std::shared_ptr<const Transform3D> navTrasform =
227  (!layerSurface.transform(gctx).isApprox(s_idTransform))
228  ? std::make_shared<const Transform3D>(layerSurface.transform(gctx))
229  : nullptr;
230  // new navigation layer
231  auto cylinderBounds =
232  std::make_shared<CylinderBounds>(navigationR, halflengthZ);
233  navigationSurface =
234  Surface::makeShared<CylinderSurface>(navTrasform, cylinderBounds);
235  } else {
236  ACTS_WARNING("Not implemented.");
237  }
238  return navigationSurface;
239 }