ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CylindricalTrackingGeometry.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file CylindricalTrackingGeometry.hpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2017-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 
9 #pragma once
10 
11 #include <functional>
12 #include <vector>
13 
33 #include "Acts/Utilities/Units.hpp"
34 
37 
38 namespace Acts {
39 namespace Test {
40 
42  std::reference_wrapper<const GeometryContext> geoContext;
43 
46  std::reference_wrapper<const GeometryContext> gctx)
47  : geoContext(gctx) {}
48 
50  std::vector<std::unique_ptr<const DetectorElementStub>> detectorStore = {};
51 
54  std::vector<Vector3D> modulePositionsCylinder(
55  double radius, double zStagger, double moduleHalfLength, double lOverlap,
56  const std::pair<int, int>& binningSchema) {
57  int nPhiBins = binningSchema.first;
58  int nZbins = binningSchema.second;
59  // prepare the return value
60  std::vector<Vector3D> mPositions;
61  mPositions.reserve(nPhiBins * nZbins);
62  // prep work
63  double phiStep = 2 * M_PI / (nPhiBins);
64  double minPhi = -M_PI + 0.5 * phiStep;
65  double zStart = -0.5 * (nZbins - 1) * (2 * moduleHalfLength - lOverlap);
66  double zStep = 2 * std::abs(zStart) / (nZbins - 1);
67  // loop over the bins
68  for (size_t zBin = 0; zBin < size_t(nZbins); ++zBin) {
69  // prepare z and r
70  double moduleZ = zStart + zBin * zStep;
71  double moduleR =
72  (zBin % 2) != 0u ? radius - 0.5 * zStagger : radius + 0.5 * zStagger;
73  for (size_t phiBin = 0; phiBin < size_t(nPhiBins); ++phiBin) {
74  // calculate the current phi value
75  double modulePhi = minPhi + phiBin * phiStep;
76  mPositions.push_back(Vector3D(moduleR * cos(modulePhi),
77  moduleR * sin(modulePhi), moduleZ));
78  }
79  }
80  return mPositions;
81  }
82 
83  // @brief Call operator for the creation method of the tracking geometry
84  std::shared_ptr<const TrackingGeometry> operator()() {
85  using namespace Acts::UnitLiterals;
86 
87  Logging::Level surfaceLLevel = Logging::INFO;
88  Logging::Level layerLLevel = Logging::INFO;
89  Logging::Level volumeLLevel = Logging::INFO;
90 
91  // configure surface array creator
92  auto surfaceArrayCreator = std::make_shared<const SurfaceArrayCreator>(
93  getDefaultLogger("SurfaceArrayCreator", surfaceLLevel));
94  // configure the layer creator that uses the surface array creator
95  LayerCreator::Config lcConfig;
96  lcConfig.surfaceArrayCreator = surfaceArrayCreator;
97  auto layerCreator = std::make_shared<const LayerCreator>(
98  lcConfig, getDefaultLogger("LayerCreator", layerLLevel));
99  // configure the layer array creator
100  LayerArrayCreator::Config lacConfig;
101  auto layerArrayCreator = std::make_shared<const LayerArrayCreator>(
102  lacConfig, getDefaultLogger("LayerArrayCreator", layerLLevel));
103 
104  // tracking volume array creator
106  auto tVolumeArrayCreator =
107  std::make_shared<const TrackingVolumeArrayCreator>(
108  tvacConfig,
109  getDefaultLogger("TrackingVolumeArrayCreator", volumeLLevel));
110  // configure the cylinder volume helper
112  cvhConfig.layerArrayCreator = layerArrayCreator;
113  cvhConfig.trackingVolumeArrayCreator = tVolumeArrayCreator;
114  auto cylinderVolumeHelper = std::make_shared<const CylinderVolumeHelper>(
115  cvhConfig, getDefaultLogger("CylinderVolumeHelper", volumeLLevel));
116 
117  // ----------------- build a beam pipe -----------------------------------
118  MaterialProperties beamPipeMaterial(makeBeryllium(), 0.8_mm);
119  PassiveLayerBuilder::Config bplConfig;
120  bplConfig.layerIdentification = "BeamPipe";
121  bplConfig.centralLayerRadii = std::vector<double>(1, 19.);
122  bplConfig.centralLayerHalflengthZ = std::vector<double>(1, 1000.);
123  bplConfig.centralLayerThickness = std::vector<double>(1, 0.8);
124  bplConfig.centralLayerMaterial = {
125  std::make_shared<const HomogeneousSurfaceMaterial>(beamPipeMaterial)};
126  auto beamPipeBuilder = std::make_shared<const PassiveLayerBuilder>(
127  bplConfig, getDefaultLogger("BeamPipeLayerBuilder", layerLLevel));
128  // create the volume for the beam pipe
130  bpvConfig.trackingVolumeHelper = cylinderVolumeHelper;
131  bpvConfig.volumeName = "BeamPipe";
132  bpvConfig.layerBuilder = beamPipeBuilder;
133  bpvConfig.layerEnvelopeR = {1_mm, 1_mm};
134  bpvConfig.buildToRadiusZero = true;
135  bpvConfig.volumeSignature = 0;
136  auto beamPipeVolumeBuilder = std::make_shared<const CylinderVolumeBuilder>(
137  bpvConfig, getDefaultLogger("BeamPipeVolumeBuilder", volumeLLevel));
138 
139  // create the bounds and the volume
140  auto beamPipeBounds =
141  std::make_shared<const CylinderVolumeBounds>(0., 25., 1100.);
142  auto beamPipeVolume = beamPipeVolumeBuilder->trackingVolume(
143  geoContext, nullptr, beamPipeBounds);
144 
145  //-------------------------------------------------------------------------------------
146  // some prep work for the material
147  // Layer material properties - thickness, X0, L0, A, Z, Rho
148  MaterialProperties lProperties(makeSilicon(), 1.5_mm);
149 
150  std::shared_ptr<const ISurfaceMaterial> layerMaterialPtr =
151  std::shared_ptr<const ISurfaceMaterial>(
152  new Acts::HomogeneousSurfaceMaterial(lProperties));
153 
154  // Module material - X0, L0, A, Z, Rho
155  Material pcMaterial = makeSilicon();
156 
157  std::vector<double> pLayerRadii = {32., 72., 116., 172.};
158  std::vector<std::pair<int, int>> pLayerBinning = {
159  {16, 14}, {32, 14}, {52, 14}, {78, 14}};
160  std::vector<double> pModuleTiltPhi = {0.145, 0.145, 0.145, 0.145};
161  std::vector<double> pModuleHalfX = {8.4, 8.4, 8.4, 8.4};
162  std::vector<double> pModuleHalfY = {36., 36., 36., 36.};
163  std::vector<double> pModuleThickness = {0.15, 0.15, 0.15, 0.15};
164 
165  std::vector<LayerPtr> pLayers;
166 
167  for (size_t ilp = 0; ilp < pLayerRadii.size(); ++ilp) {
168  std::vector<std::shared_ptr<const Surface>> layerModules;
169 
170  // Module material from input
171  MaterialProperties moduleMaterialProperties(pcMaterial,
172  pModuleThickness[ilp]);
173  // Create a new surface material
174  std::shared_ptr<const ISurfaceMaterial> moduleMaterialPtr =
175  std::shared_ptr<const ISurfaceMaterial>(
176  new Acts::HomogeneousSurfaceMaterial(moduleMaterialProperties));
177 
178  // The rectangle bounds for all modules
179  auto mBounds = std::make_shared<RectangleBounds>(pModuleHalfX[ilp],
180  pModuleHalfY[ilp]);
181  // Create the module centers
182  auto moduleCenters = modulePositionsCylinder(
183  pLayerRadii[ilp], 2_mm, pModuleHalfY[ilp], 5_mm, pLayerBinning[ilp]);
184 
185  for (auto& mCenter : moduleCenters) {
186  // The association transform
187  double modulePhi = VectorHelpers::phi(mCenter);
188  // Local z axis is the normal vector
189  Vector3D moduleLocalZ(cos(modulePhi + pModuleTiltPhi[ilp]),
190  sin(modulePhi + pModuleTiltPhi[ilp]), 0.);
191  // Local y axis is the global z axis
192  Vector3D moduleLocalY(0., 0., 1);
193  // Local x axis the normal to local y,z
194  Vector3D moduleLocalX(-sin(modulePhi + pModuleTiltPhi[ilp]),
195  cos(modulePhi + pModuleTiltPhi[ilp]), 0.);
196  // Create the RotationMatrix
197  RotationMatrix3D moduleRotation;
198  moduleRotation.col(0) = moduleLocalX;
199  moduleRotation.col(1) = moduleLocalY;
200  moduleRotation.col(2) = moduleLocalZ;
201  // Get the moduleTransform
202  std::shared_ptr<Transform3D> mModuleTransform =
203  std::make_shared<Transform3D>(Translation3D(mCenter) *
204  moduleRotation);
205  // Create the detector element
206  auto detElement = std::make_unique<const DetectorElementStub>(
207  mModuleTransform, mBounds, pModuleThickness[ilp],
208  moduleMaterialPtr);
209 
210  layerModules.push_back(detElement->surface().getSharedPtr());
211  detectorStore.push_back(std::move(detElement));
212  }
213  // create the layer and store it
214  ProtoLayer protoLayer(geoContext, layerModules);
215  protoLayer.envR = {0.5, 0.5};
216  auto pLayer = layerCreator->cylinderLayer(
217  geoContext, std::move(layerModules), pLayerBinning[ilp].first,
218  pLayerBinning[ilp].second, protoLayer);
219  auto approachSurfaces = pLayer->approachDescriptor()->containedSurfaces();
220  auto mutableOuterSurface =
221  const_cast<Acts::Surface*>(approachSurfaces.at(1));
222  mutableOuterSurface->assignSurfaceMaterial(layerMaterialPtr);
224  pLayers.push_back(pLayer);
225 
226  } // loop over layers
227 
228  // layer array
229  auto pLayerArray = layerArrayCreator->layerArray(geoContext, pLayers, 25.,
230  300., arbitrary, binR);
231  auto pVolumeBounds =
232  std::make_shared<const CylinderVolumeBounds>(25., 300., 1100.);
233  // create the Tracking volume
234  auto pVolume = TrackingVolume::create(nullptr, pVolumeBounds, nullptr,
235  std::move(pLayerArray), nullptr, {},
236  "Pixel::Barrel");
237 
238  // The combined volume
239  auto detectorVolume = cylinderVolumeHelper->createContainerTrackingVolume(
240  geoContext, {beamPipeVolume, pVolume});
241 
242  // create and return the geometry
243  return std::make_shared<const TrackingGeometry>(detectorVolume);
244  }
245 };
246 
247 } // namespace Test
248 } // namespace Acts