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