Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Channelizer.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file Channelizer.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2020 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 
17 
18 #include <algorithm>
19 #include <cmath>
20 #include <memory>
21 
22 std::vector<ActsFatras::Channelizer::ChannelSegment>
24  const Acts::Surface& surface,
25  const Acts::BinUtility& segmentation,
26  const Segment2D& segment) const {
27  // Return if the segmentation is not two-dimensional
28  // (strips need to have one bin along the strip)
29  if (segmentation.dimensions() != 2) {
30  return {};
31  }
32 
33  // Start and end point
34  const auto& start = segment[0];
35  const auto& end = segment[1];
36 
37  // Full path length - the full channel
38  auto segment2d = (end - start);
39  std::vector<ChannelStep> cSteps;
40  Bin2D bstart = {0, 0};
41  Bin2D bend = {0, 0};
42 
43  if (surface.type() == Acts::Surface::SurfaceType::Plane) {
44  // Get the segmentation and convert it to lines & arcs
45  bstart = {static_cast<unsigned int>(segmentation.bin(start, 0)),
46  static_cast<unsigned int>(segmentation.bin(start, 1))};
47  bend = {static_cast<unsigned int>(segmentation.bin(end, 0)),
48  static_cast<unsigned int>(segmentation.bin(end, 1))};
49  // Fast single channel exit
50  if (bstart == bend) {
51  return {ChannelSegment(bstart, {start, end}, segment2d.norm())};
52  }
53  // The lines channel segment lines along x
54  if (bstart[0] != bend[0]) {
55  double k = segment2d.y() / segment2d.x();
56  double d = start.y() - k * start.x();
57 
58  const auto& xboundaries = segmentation.binningData()[0].boundaries();
59  std::vector<double> xbbounds = {
60  xboundaries.begin() + std::min(bstart[0], bend[0]) + 1,
61  xboundaries.begin() + std::max(bstart[0], bend[0]) + 1};
62  for (const auto x : xbbounds) {
63  cSteps.push_back(ChannelStep{
64  {(bstart[0] < bend[0] ? 1 : -1), 0}, {x, k * x + d}, start});
65  }
66  }
67  // The lines channel segment lines along y
68  if (bstart[1] != bend[1]) {
69  double k = segment2d.x() / segment2d.y();
70  double d = start.x() - k * start.y();
71  const auto& yboundaries = segmentation.binningData()[1].boundaries();
72  std::vector<double> ybbounds = {
73  yboundaries.begin() + std::min(bstart[1], bend[1]) + 1,
74  yboundaries.begin() + std::max(bstart[1], bend[1]) + 1};
75  for (const auto y : ybbounds) {
76  cSteps.push_back(ChannelStep{
77  {0, (bstart[1] < bend[1] ? 1 : -1)}, {k * y + d, y}, start});
78  }
79  }
80 
81  } else if (surface.type() == Acts::Surface::SurfaceType::Disc) {
86 
87  // Get the segmentation and convert it to lines & arcs
88  bstart = {static_cast<unsigned int>(segmentation.bin(pstart, 0)),
89  static_cast<unsigned int>(segmentation.bin(pstart, 1))};
90  bend = {static_cast<unsigned int>(segmentation.bin(pend, 0)),
91  static_cast<unsigned int>(segmentation.bin(pend, 1))};
92 
93  // Fast single channel exit
94  if (bstart == bend) {
95  return {ChannelSegment(bstart, {start, end}, segment2d.norm())};
96  }
97 
98  double phistart = pstart[1];
99  double phiend = pend[1];
100 
101  // The radial boundaries
102  if (bstart[0] != bend[0]) {
103  const auto& rboundaries = segmentation.binningData()[0].boundaries();
104  std::vector<double> rbbounds = {
105  rboundaries.begin() + std::min(bstart[0], bend[0]) + 1,
106  rboundaries.begin() + std::max(bstart[0], bend[0]) + 1};
107  for (const auto& r : rbbounds) {
108  auto radIntersection =
110  r, std::min(phistart, phiend), std::max(phistart, phiend),
111  start, (end - start).normalized());
112  cSteps.push_back(ChannelStep{{(bstart[0] < bend[0] ? 1 : -1), 0},
113  radIntersection.position(),
114  start});
115  }
116  }
117  // The phi boundaries
118  if (bstart[1] != bend[1]) {
119  double referenceR = surface.binningPositionValue(geoCtx, Acts::binR);
120  Acts::Vector2 origin = {0., 0.};
121  const auto& phiboundaries = segmentation.binningData()[1].boundaries();
122  std::vector<double> phibbounds = {
123  phiboundaries.begin() + std::min(bstart[1], bend[1]) + 1,
124  phiboundaries.begin() + std::max(bstart[1], bend[1]) + 1};
125 
126  for (const auto& phi : phibbounds) {
127  Acts::Vector2 philine(referenceR * std::cos(phi),
128  referenceR * std::sin(phi));
129  auto phiIntersection =
131  origin, philine, start, (end - start).normalized());
132  cSteps.push_back(ChannelStep{{0, (bstart[1] < bend[1] ? 1 : -1)},
133  phiIntersection.position(),
134  start});
135  }
136  }
137  }
138 
139  // Register the last step if successful
140  if (not cSteps.empty()) {
141  cSteps.push_back(ChannelStep({0, 0}, end, start));
142  std::sort(cSteps.begin(), cSteps.end());
143  }
144 
145  std::vector<ChannelSegment> cSegments;
146  cSegments.reserve(cSteps.size());
147 
148  Bin2D currentBin = {bstart[0], bstart[1]};
149  BinDelta2D lastDelta = {0, 0};
150  Acts::Vector2 lastIntersect = start;
151  double lastPath = 0.;
152  for (auto& cStep : cSteps) {
153  currentBin[0] += lastDelta[0];
154  currentBin[1] += lastDelta[1];
155  double path = cStep.path - lastPath;
156  cSegments.push_back(
157  ChannelSegment(currentBin, {lastIntersect, cStep.intersect}, path));
158  lastPath = cStep.path;
159  lastDelta = cStep.delta;
160  lastIntersect = cStep.intersect;
161  }
162 
163  return cSegments;
164 }