Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
BuildGenericDetector.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file BuildGenericDetector.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 
11 #include <cmath>
12 
13 namespace ActsExamples {
14 
15 namespace Generic {
16 
18 std::vector<Acts::Vector3> modulePositionsCylinder(
19  double radius, double zStagger, double moduleHalfLength, double lOverlap,
20  const std::pair<int, int>& binningSchema) {
21  int nPhiBins = binningSchema.first;
22  int nZbins = binningSchema.second;
23  // prepare the return value
24  std::vector<Acts::Vector3> mPositions;
25  mPositions.reserve(nPhiBins * nZbins);
26  // prep work
27  double phiStep = 2 * M_PI / (nPhiBins);
28  double minPhi = -M_PI + 0.5 * phiStep;
29  double zStart = -0.5 * (nZbins - 1) * (2 * moduleHalfLength - lOverlap);
30  double zStep = 2 * std::abs(zStart) / (nZbins - 1);
31  // loop over the bins
32  for (size_t zBin = 0; zBin < size_t(nZbins); ++zBin) {
33  // prepare z and r
34  double moduleZ = zStart + zBin * zStep;
35  double moduleR =
36  (zBin % 2) != 0u ? radius - 0.5 * zStagger : radius + 0.5 * zStagger;
37  for (size_t phiBin = 0; phiBin < size_t(nPhiBins); ++phiBin) {
38  // calculate the current phi value
39  double modulePhi = minPhi + phiBin * phiStep;
40  mPositions.push_back(Acts::Vector3(moduleR * cos(modulePhi),
41  moduleR * sin(modulePhi), moduleZ));
42  }
43  }
44  return mPositions;
45 }
46 
48 std::vector<std::vector<Acts::Vector3>> modulePositionsDisc(
49  double z, double ringStagger, std::vector<double> phiStagger,
50  std::vector<double> phiSubStagger, double innerRadius, double outerRadius,
51  const std::vector<size_t>& discBinning,
52  const std::vector<double>& moduleHalfLength) {
53  // calculate the radii
54  std::vector<double> radii;
55  // calculate the radial borders
56  std::vector<double> radialBoarders;
57  // the radial span of the disc
58  double deltaR = outerRadius - innerRadius;
59  // quick exits
60  if (discBinning.size() == 1) {
61  radii.push_back(0.5 * (innerRadius + outerRadius));
62  radialBoarders = {innerRadius, outerRadius};
63  } else {
64  double totalLength = 0;
65  // sum up the total length
66  for (auto& mhlength : moduleHalfLength) {
67  totalLength += 2 * mhlength;
68  }
69  // now calculate the overlap (equal pay)
70  double rOverlap = (totalLength - deltaR) / (moduleHalfLength.size() - 1);
71  // and now fill the radii and gaps
72  double lastR = innerRadius;
73  double lastHl = 0.;
74  double lastOl = 0.;
75  // remember the radial boarders
76  radialBoarders.push_back(innerRadius);
77  // now calculate
78  for (auto& mhlength : moduleHalfLength) {
79  // calculate the radius
80  radii.push_back(lastR + lastHl - lastOl + mhlength);
81  lastR = radii[radii.size() - 1];
82  lastOl = rOverlap;
83  lastHl = mhlength;
84  // and register the radial boarder
85  radialBoarders.push_back(lastR + 2 * lastHl - 0.5 * lastOl);
86  }
87  }
88  // now prepare the return method
89  std::vector<std::vector<Acts::Vector3>> mPositions;
90  for (size_t ir = 0; ir < radii.size(); ++ir) {
91  // generate the z value
92  // convention inner ring is closer to origin : makes sense
93  double rz = radii.size() == 1 ? z
94  : ((ir % 2) != 0u ? z + 0.5 * ringStagger
95  : z - 0.5 * ringStagger);
96  // fill the ring positions
97  double psStagger = phiSubStagger.empty() ? 0. : phiSubStagger[ir];
98  mPositions.push_back(modulePositionsRing(rz, radii[ir], phiStagger[ir],
99  psStagger, discBinning[ir]));
100  }
101  return mPositions;
102 }
103 
105 std::vector<Acts::Vector3> modulePositionsRing(double z, double radius,
106  double phiStagger,
107  double phiSubStagger,
108  int nPhiBins) {
109  // create and fill the positions
110  std::vector<Acts::Vector3> rPositions;
111  rPositions.reserve(nPhiBins);
112  // prep work
113  double phiStep = 2 * M_PI / (nPhiBins);
114  double minPhi = -M_PI + 0.5 * phiStep;
115  // phi loop
116  for (size_t iphi = 0; iphi < size_t(nPhiBins); ++iphi) {
117  // if we have a phi sub stagger presents
118  double rzs = 0.;
119  // phi stagger affects 0 vs 1, 2 vs 3 ... etc
120  // -> only works if it is a %4
121  // phi sub stagger affects 2 vs 4, 1 vs 3 etc.
122  if (phiSubStagger != 0. && ((nPhiBins % 4) == 0)) {
123  // switch sides
124  if ((iphi % 4) == 0u) {
125  rzs = phiSubStagger;
126  } else if (((iphi + 1) % 4) == 0u) {
127  rzs = -phiSubStagger;
128  }
129  }
130  // the module phi
131  double phi = minPhi + iphi * phiStep;
132  // main z position depending on phi bin
133  double rz = (iphi % 2) != 0u ? z - 0.5 * phiStagger : z + 0.5 * phiStagger;
134  rPositions.push_back(
135  Acts::Vector3(radius * cos(phi), radius * sin(phi), rz + rzs));
136  }
137  return rPositions;
138 }
139 
140 } // end of namespace Generic
141 
142 } // end of namespace ActsExamples