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