Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TrackFindingFromPrototrackAlgorithm.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file TrackFindingFromPrototrackAlgorithm.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 
13 
14 #include <boost/accumulators/accumulators.hpp>
15 #include <boost/accumulators/statistics.hpp>
16 
17 namespace {
18 
19 using namespace ActsExamples;
20 
21 struct ProtoTrackSourceLinkAccessor
22  : GeometryIdMultisetAccessor<IndexSourceLink> {
25 
26  std::unique_ptr<const Acts::Logger> loggerPtr;
27  Container protoTrackSourceLinks;
28 
29  // get the range of elements with requested geoId
30  std::pair<Iterator, Iterator> range(const Acts::Surface& surface) const {
31  const auto& logger = *loggerPtr;
32 
33  if (protoTrackSourceLinks.contains(surface.geometryId())) {
34  auto [begin, end] =
35  protoTrackSourceLinks.equal_range(surface.geometryId());
36  ACTS_VERBOSE("Select " << std::distance(begin, end)
37  << " source-links from prototrack on "
38  << surface.geometryId());
39  return {Iterator{begin}, Iterator{end}};
40  }
41 
42  assert(container != nullptr);
43  auto [begin, end] = container->equal_range(surface.geometryId());
44  ACTS_VERBOSE("Select " << std::distance(begin, end)
45  << " source-links from collection on "
46  << surface.geometryId());
47  return {Iterator{begin}, Iterator{end}};
48  }
49 };
50 } // namespace
51 
52 namespace ActsExamples {
53 
54 TrackFindingFromPrototrackAlgorithm::TrackFindingFromPrototrackAlgorithm(
56  : IAlgorithm(cfg.tag + "CkfFromProtoTracks", lvl), m_cfg(cfg) {
62 }
63 
65  const ActsExamples::AlgorithmContext& ctx) const {
66  const auto& measurements = m_inputMeasurements(ctx);
67  const auto& sourceLinks = m_inputSourceLinks(ctx);
68  const auto& protoTracks = m_inputProtoTracks(ctx);
69  const auto& initialParameters = m_inputInitialTrackParameters(ctx);
70 
71  if (initialParameters.size() != protoTracks.size()) {
72  ACTS_FATAL("Inconsistent number of parameters and prototracks");
73  return ProcessCode::ABORT;
74  }
75 
76  // Construct a perigee surface as the target surface
77  auto pSurface = Acts::Surface::makeShared<Acts::PerigeeSurface>(
78  Acts::Vector3{0., 0., 0.});
79 
81  pOptions.maxSteps = 10000;
82 
83  PassThroughCalibrator pcalibrator;
84  MeasurementCalibratorAdapter calibrator(pcalibrator, measurements);
85  Acts::GainMatrixUpdater kfUpdater;
86  Acts::GainMatrixSmoother kfSmoother;
88 
90  extensions;
92  &calibrator);
93  extensions.updater.connect<
94  &Acts::GainMatrixUpdater::operator()<Acts::VectorMultiTrajectory>>(
95  &kfUpdater);
96  extensions.smoother.connect<
97  &Acts::GainMatrixSmoother::operator()<Acts::VectorMultiTrajectory>>(
98  &kfSmoother);
99  extensions.measurementSelector
100  .connect<&Acts::MeasurementSelector::select<Acts::VectorMultiTrajectory>>(
101  &measSel);
102 
103  // The source link accessor
104  ProtoTrackSourceLinkAccessor sourceLinkAccessor;
105  sourceLinkAccessor.loggerPtr = logger().clone("SourceLinkAccessor");
106  sourceLinkAccessor.container = &sourceLinks;
107 
109  slAccessorDelegate;
110  slAccessorDelegate.connect<&ProtoTrackSourceLinkAccessor::range>(
111  &sourceLinkAccessor);
112 
113  // Set the CombinatorialKalmanFilter options
115  ctx.geoContext, ctx.magFieldContext, ctx.calibContext, slAccessorDelegate,
116  extensions, pOptions, &(*pSurface));
117 
118  // Perform the track finding for all initial parameters
119  ACTS_DEBUG("Invoke track finding with " << initialParameters.size()
120  << " seeds.");
121 
122  auto trackContainer = std::make_shared<Acts::VectorTrackContainer>();
123  auto trackStateContainer = std::make_shared<Acts::VectorMultiTrajectory>();
124 
125  TrackContainer tracks(trackContainer, trackStateContainer);
126 
127  tracks.addColumn<unsigned int>("trackGroup");
128  Acts::TrackAccessor<unsigned int> seedNumber("trackGroup");
129 
130  std::size_t nSeed = 0;
131  std::size_t nFailed = 0;
132 
133  std::vector<std::size_t> nTracksPerSeeds;
134  nTracksPerSeeds.reserve(initialParameters.size());
135 
136  for (auto i = 0ul; i < initialParameters.size(); ++i) {
137  sourceLinkAccessor.protoTrackSourceLinks.clear();
138 
139  // Fill the source links via their indices from the container
140  for (const auto hitIndex : protoTracks.at(i)) {
141  if (auto it = sourceLinks.nth(hitIndex); it != sourceLinks.end()) {
142  sourceLinkAccessor.protoTrackSourceLinks.insert(*it);
143  } else {
144  ACTS_FATAL("Proto track " << i << " contains invalid hit index"
145  << hitIndex);
146  return ProcessCode::ABORT;
147  }
148  }
149 
150  auto result = (*m_cfg.findTracks)(initialParameters.at(i), options, tracks);
151  nSeed++;
152 
153  if (!result.ok()) {
154  nFailed++;
155  ACTS_WARNING("Track finding failed for proto track " << i << " with error"
156  << result.error());
157  continue;
158  }
159 
160  auto& tracksForSeed = result.value();
161 
162  nTracksPerSeeds.push_back(tracksForSeed.size());
163 
164  for (auto& track : tracksForSeed) {
165  seedNumber(track) = nSeed;
166  }
167  }
168 
169  {
170  std::lock_guard<std::mutex> guard(m_mutex);
171 
172  std::copy(nTracksPerSeeds.begin(), nTracksPerSeeds.end(),
173  std::back_inserter(m_nTracksPerSeeds));
174  }
175 
176  // TODO The computeSharedHits function is still a member function of
177  // TrackFindingAlgorithm, but could also be a free function. Uncomment this
178  // once this is done.
179  // Compute shared hits from all the reconstructed tracks if
180  // (m_cfg.computeSharedHits) {
181  // computeSharedHits(sourceLinks, tracks);
182  // }
183 
184  ACTS_INFO("Event " << ctx.eventNumber << ": " << nFailed << " / " << nSeed
185  << " failed (" << ((100.f * nFailed) / nSeed) << "%)");
186  ACTS_DEBUG("Finalized track finding with " << tracks.size()
187  << " track candidates.");
188  auto constTrackStateContainer =
189  std::make_shared<Acts::ConstVectorMultiTrajectory>(
190  std::move(*trackStateContainer));
191 
192  auto constTrackContainer = std::make_shared<Acts::ConstVectorTrackContainer>(
193  std::move(*trackContainer));
194 
195  ConstTrackContainer constTracks{constTrackContainer,
196  constTrackStateContainer};
197 
198  m_outputTracks(ctx, std::move(constTracks));
200 }
201 
204 
205  ACTS_INFO("TrackFindingFromPrototracksAlgorithm statistics:");
206  namespace ba = boost::accumulators;
207  using Accumulator = ba::accumulator_set<
208  float, ba::features<ba::tag::sum, ba::tag::mean, ba::tag::variance>>;
209 
210  Accumulator totalAcc;
211  std::for_each(m_nTracksPerSeeds.begin(), m_nTracksPerSeeds.end(),
212  [&](auto v) { totalAcc(static_cast<float>(v)); });
213  ACTS_INFO("- total number tracks: " << ba::sum(totalAcc));
214  ACTS_INFO("- avg tracks per seed: " << ba::mean(totalAcc) << " +- "
215  << std::sqrt(ba::variance(totalAcc)));
216 
217  return {};
218 }
219 
220 } // namespace ActsExamples