EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
FittingAlgorithm.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file FittingAlgorithm.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2019 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 
15 
16 #include <stdexcept>
17 
20  : ActsExamples::BareAlgorithm("FittingAlgorithm", level),
21  m_cfg(std::move(cfg)) {
22  if (m_cfg.inputSourceLinks.empty()) {
23  throw std::invalid_argument("Missing input source links collection");
24  }
25  if (m_cfg.inputProtoTracks.empty()) {
26  throw std::invalid_argument("Missing input proto tracks collection");
27  }
28  if (m_cfg.inputInitialTrackParameters.empty()) {
29  throw std::invalid_argument(
30  "Missing input initial track parameters collection");
31  }
32  if (m_cfg.outputTrajectories.empty()) {
33  throw std::invalid_argument("Missing output trajectories collection");
34  }
35 }
36 
38  const ActsExamples::AlgorithmContext& ctx) const {
39  // Read input data
40  const auto sourceLinks =
41  ctx.eventStore.get<SimSourceLinkContainer>(m_cfg.inputSourceLinks);
42  const auto protoTracks =
43  ctx.eventStore.get<ProtoTrackContainer>(m_cfg.inputProtoTracks);
44  const auto initialParameters = ctx.eventStore.get<TrackParametersContainer>(
45  m_cfg.inputInitialTrackParameters);
46 
47  // Consistency cross checks
48  if (protoTracks.size() != initialParameters.size()) {
49  ACTS_FATAL("Inconsistent number of proto tracks and parameters");
50  return ProcessCode::ABORT;
51  }
52 
53  // Prepare the output data with MultiTrajectory
54  TrajectoryContainer trajectories;
55  trajectories.reserve(protoTracks.size());
56 
57  // Construct a perigee surface as the target surface
58  auto pSurface = Acts::Surface::makeShared<Acts::PerigeeSurface>(
59  Acts::Vector3D{0., 0., 0.});
60 
61  // Set the KalmanFitter options
65  Acts::PropagatorPlainOptions(), &(*pSurface));
66 
67  // Perform the fit for each input track
68  std::vector<SimSourceLink> trackSourceLinks;
69  for (std::size_t itrack = 0; itrack < protoTracks.size(); ++itrack) {
70  // The list of hits and the initial start parameters
71  const auto& protoTrack = protoTracks[itrack];
72  const auto& initialParams = initialParameters[itrack];
73 
74  // We can have empty tracks which must give empty fit results
75  if (protoTrack.empty()) {
76  trajectories.push_back(SimMultiTrajectory());
77  ACTS_WARNING("Empty track " << itrack << " found.");
78  continue;
79  }
80 
81  // Clear & reserve the right size
82  trackSourceLinks.clear();
83  trackSourceLinks.reserve(protoTrack.size());
84 
85  // Fill the source links via their indices from the container
86  for (auto hitIndex : protoTrack) {
87  auto sourceLink = sourceLinks.nth(hitIndex);
88  if (sourceLink == sourceLinks.end()) {
89  ACTS_FATAL("Proto track " << itrack << " contains invalid hit index"
90  << hitIndex);
91  return ProcessCode::ABORT;
92  }
93  trackSourceLinks.push_back(*sourceLink);
94  }
95 
96  ACTS_DEBUG("Invoke fitter");
97  auto result = m_cfg.fit(trackSourceLinks, initialParams, kfOptions);
98  if (result.ok()) {
99  // Get the fit output object
100  const auto& fitOutput = result.value();
101  // The track entry indices container. One element here.
102  std::vector<size_t> trackTips;
103  trackTips.reserve(1);
104  trackTips.emplace_back(fitOutput.trackTip);
105  // The fitted parameters container. One element (at most) here.
106  IndexedParams indexedParams;
107  if (fitOutput.fittedParameters) {
108  const auto& params = fitOutput.fittedParameters.value();
109  ACTS_VERBOSE("Fitted paramemeters for track " << itrack);
110  ACTS_VERBOSE(" " << params.parameters().transpose());
111  // Push the fitted parameters to the container
112  indexedParams.emplace(fitOutput.trackTip, std::move(params));
113  } else {
114  ACTS_DEBUG("No fitted paramemeters for track " << itrack);
115  }
116  // Create a SimMultiTrajectory
117  trajectories.emplace_back(std::move(fitOutput.fittedStates),
118  std::move(trackTips), std::move(indexedParams));
119  } else {
120  ACTS_WARNING("Fit failed for track " << itrack << " with error"
121  << result.error());
122  // Fit failed, but still create an empty SimMultiTrajectory
123  trajectories.push_back(SimMultiTrajectory());
124  }
125  }
126 
127  ctx.eventStore.add(m_cfg.outputTrajectories, std::move(trajectories));
129 }