Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PrototracksToParameters.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file PrototracksToParameters.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2023 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 
18 #include "Acts/Utilities/Zip.hpp"
24 
25 #include <algorithm>
26 
27 using namespace ActsExamples;
28 using namespace Acts::UnitLiterals;
29 
30 namespace ActsExamples {
31 
34  : IAlgorithm("PrototracksToParsAndSeeds", lvl), m_cfg(std::move(cfg)) {
40 
41  if (m_cfg.geometry == nullptr) {
42  throw std::invalid_argument("No geometry given");
43  }
44  if (m_cfg.magneticField == nullptr) {
45  throw std::invalid_argument("No magnetic field given");
46  }
47 
48  // Set up the track parameters covariance (the same for all tracks)
49  for (std::size_t i = Acts::eBoundLoc0; i < Acts::eBoundSize; ++i) {
52  }
53 }
54 
56 
58  const AlgorithmContext &ctx) const {
59  auto bCache = m_cfg.magneticField->makeCache(ctx.magFieldContext);
60  const auto &sps = m_inputSpacePoints(ctx);
61  auto prototracks = m_inputProtoTracks(ctx);
62 
63  // Make some lookup tables. Allocate space for the maximum number of indices
64  // (max 2 source links per spacepoint)
65  std::vector<const SimSpacePoint *> indexToSpacepoint(2 * sps.size(), nullptr);
66  std::vector<Acts::GeometryIdentifier> indexToGeoId(
67  2 * sps.size(), Acts::GeometryIdentifier{0});
68 
69  for (const auto &sp : sps) {
70  for (const auto &sl : sp.sourceLinks()) {
71  const auto &isl = sl.template get<IndexSourceLink>();
72  indexToSpacepoint[isl.index()] = &sp;
73  indexToGeoId[isl.index()] = isl.geometryId();
74  }
75  }
76 
77  ProtoTrackContainer seededTracks;
78  seededTracks.reserve(prototracks.size());
79 
80  SimSeedContainer seeds;
81  seeds.reserve(prototracks.size());
82 
84  parameters.reserve(prototracks.size());
85 
86  // Loop over the prototracks to make seeds
87  ProtoTrack tmpTrack;
88  std::vector<const SimSpacePoint *> tmpSps;
89  std::size_t skippedTracks = 0;
90  for (auto &track : prototracks) {
91  ACTS_VERBOSE("Try to get seed from prototrack with " << track.size()
92  << " hits");
93  // Make prototrack unique with respect to volume and layer
94  // so we don't get a seed where we have two spacepoints on the same layer
95 
96  // Here, we want to create a seed only if the prototrack with removed unique
97  // layer-volume spacepoints has 3 or more hits. However, if this is the
98  // case, we want to keep the whole prototrack. Therefore, we operate on a
99  // tmpTrack.
100  std::sort(track.begin(), track.end(), [&](auto a, auto b) {
101  if (indexToGeoId[a].volume() != indexToGeoId[b].volume()) {
102  return indexToGeoId[a].volume() < indexToGeoId[b].volume();
103  }
104  return indexToGeoId[a].layer() < indexToGeoId[b].layer();
105  });
106 
107  tmpTrack.clear();
108  std::unique_copy(
109  track.begin(), track.end(), std::back_inserter(tmpTrack),
110  [&](auto a, auto b) {
111  return indexToGeoId[a].volume() == indexToGeoId[b].volume() &&
112  indexToGeoId[a].layer() == indexToGeoId[b].layer();
113  });
114 
115  // in this case we cannot seed properly
116  if (tmpTrack.size() < 3) {
117  ACTS_DEBUG(
118  "Cannot seed because less then three hits with unique (layer, "
119  "volume)");
120  skippedTracks++;
121  continue;
122  }
123 
124  // Make the seed
125  tmpSps.clear();
126  std::transform(track.begin(), track.end(), std::back_inserter(tmpSps),
127  [&](auto i) { return indexToSpacepoint[i]; });
128  tmpSps.erase(std::remove_if(tmpSps.begin(), tmpSps.end(),
129  [](auto sp) { return sp == nullptr; }),
130  tmpSps.end());
131 
132  if (tmpSps.size() < 3) {
133  ACTS_WARNING("Could not find all spacepoints, skip");
134  skippedTracks++;
135  continue;
136  }
137 
138  std::sort(tmpSps.begin(), tmpSps.end(),
139  [](const auto &a, const auto &b) { return a->r() < b->r(); });
140 
141  // Simply use r = m*z + t and solve for r=0 to find z vertex position...
142  // Probably not the textbook way to do
143  const auto m = (tmpSps.back()->r() - tmpSps.front()->r()) /
144  (tmpSps.back()->z() - tmpSps.front()->z());
145  const auto t = tmpSps.front()->r() - m * tmpSps.front()->z();
146  const auto z_vertex = -t / m;
147  const auto s = tmpSps.size();
148 
149  SimSeed seed =
151  ? SimSeed(*tmpSps[0], *tmpSps[1], *tmpSps[2], z_vertex)
152  : SimSeed(*tmpSps[0], *tmpSps[s / 2], *tmpSps[s - 1], z_vertex);
153 
154  // Compute parameters
155  const auto &bottomSP = seed.sp().front();
156  const auto geoId = bottomSP->sourceLinks()
157  .front()
158  .template get<IndexSourceLink>()
159  .geometryId();
160  const auto &surface = *m_cfg.geometry->findSurface(geoId);
161 
162  auto field = m_cfg.magneticField->getField(
163  {bottomSP->x(), bottomSP->y(), bottomSP->z()}, bCache);
164  if (!field.ok()) {
165  ACTS_ERROR("Field lookup error: " << field.error());
166  return ProcessCode::ABORT;
167  }
168 
170  ctx.geoContext, seed.sp().begin(), seed.sp().end(), surface, *field,
171  m_cfg.bFieldMin);
172 
173  if (not pars) {
174  ACTS_WARNING("Skip track because of bad params");
175  }
176 
177  seededTracks.push_back(track);
178  seeds.emplace_back(std::move(seed));
179  parameters.push_back(Acts::BoundTrackParameters(
180  surface.getSharedPtr(), *pars, m_covariance, m_cfg.particleHypothesis));
181  }
182 
183  if (skippedTracks > 0) {
184  ACTS_WARNING("Skipped seeding of " << skippedTracks);
185  }
186 
187  ACTS_DEBUG("Seeded " << seeds.size() << " out of " << prototracks.size()
188  << " prototracks");
189 
190  m_outputSeeds(ctx, std::move(seeds));
191  m_outputProtoTracks(ctx, std::move(seededTracks));
192  m_outputParameters(ctx, std::move(parameters));
193 
194  return ProcessCode::SUCCESS;
195 }
196 
197 } // namespace ActsExamples