Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
EDM4hepUtil.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file EDM4hepUtil.hpp
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 #pragma once
9 
26 
27 #include <stdexcept>
28 
29 #include <Eigen/src/Core/util/Memory.h>
30 #include <boost/graph/graph_traits.hpp>
31 #include <edm4hep/Track.h>
32 #include <edm4hep/TrackState.h>
33 
34 #include "edm4hep/MutableTrack.h"
35 
36 namespace Acts {
37 namespace EDM4hepUtil {
38 
39 static constexpr std::int32_t EDM4HEP_ACTS_POSITION_TYPE = 42;
40 
41 namespace detail {
42 struct Parameters {
44  // Dummy default
46  std::optional<Acts::BoundSquareMatrix> covariance;
47  std::shared_ptr<const Acts::Surface> surface;
48 };
49 
50 ActsSquareMatrix<6> jacobianToEdm4hep(double theta, double qOverP, double Bz);
51 
52 ActsSquareMatrix<6> jacobianFromEdm4hep(double tanLambda, double omega,
53  double Bz);
54 
55 void unpackCovariance(const float* from, ActsSquareMatrix<6>& to);
56 void packCovariance(const ActsSquareMatrix<6>& from, float* to);
57 
59  double Bz,
60  const BoundTrackParameters& params);
61 
63  double Bz, const Parameters& params);
64 
65 } // namespace detail
66 
67 template <typename track_container_t, typename track_state_container_t,
68  template <typename> class holder_t>
72  track,
73  edm4hep::MutableTrack to, double Bz,
74  const Logger& logger = getDummyLogger()) {
75  ACTS_VERBOSE("Converting track to EDM4hep");
76  to.setChi2(track.chi2());
77  to.setNdf(track.nDoF());
78 
79  std::vector<edm4hep::TrackState> outTrackStates;
80  outTrackStates.reserve(track.nTrackStates());
81 
82  auto setParameters = [](edm4hep::TrackState& trackState,
83  const detail::Parameters& params) {
84  trackState.D0 = params.values[0];
85  trackState.Z0 = params.values[1];
86  trackState.phi = params.values[2];
87  trackState.tanLambda = params.values[3];
88  trackState.omega = params.values[4];
89  trackState.time = params.values[5];
90 
91  if (params.covariance) {
92  detail::packCovariance(params.covariance.value(),
93  trackState.covMatrix.data());
94  }
95  };
96 
97  ACTS_VERBOSE("Converting " << track.nTrackStates() << " track states");
98 
99  for (const auto& state : track.trackStatesReversed()) {
100  auto typeFlags = state.typeFlags();
101  if (!typeFlags.test(Acts::TrackStateFlag::MeasurementFlag)) {
102  continue;
103  }
104 
105  edm4hep::TrackState& trackState = outTrackStates.emplace_back();
106  trackState.location = edm4hep::TrackState::AtOther;
107 
108  BoundTrackParameters params{state.referenceSurface().getSharedPtr(),
109  state.parameters(), state.covariance(),
110  track.particleHypothesis()};
111 
112  // Convert to LCIO track parametrization expected by EDM4hep
113  detail::Parameters converted =
114  detail::convertTrackParametersToEdm4hep(gctx, Bz, params);
115 
116  // Write the converted parameters to the EDM4hep track state
117  setParameters(trackState, converted);
118  ACTS_VERBOSE("- parameters: " << state.parameters().transpose() << " -> "
119  << converted.values.transpose());
120  ACTS_VERBOSE("- covariance: \n"
121  << state.covariance() << "\n->\n"
122  << converted.covariance.value());
123 
124  // Converted parameters are relative to an ad-hoc perigee surface created at
125  // the hit location
126  auto center = converted.surface->center(gctx);
127  trackState.referencePoint.x = center.x();
128  trackState.referencePoint.y = center.y();
129  trackState.referencePoint.z = center.z();
130  ACTS_VERBOSE("- ref surface ctr: " << center.transpose());
131  }
132  outTrackStates.front().location = edm4hep::TrackState::AtLastHit;
133  outTrackStates.back().location = edm4hep::TrackState::AtFirstHit;
134 
135  // Add a track state that represents the IP parameters
136  auto& ipState = outTrackStates.emplace_back();
137 
138  // Convert the track parameters at the IP
139  BoundTrackParameters trackParams{track.referenceSurface().getSharedPtr(),
140  track.parameters(), track.covariance(),
141  track.particleHypothesis()};
142 
143  // Convert to LCIO track parametrization expected by EDM4hep
144  auto converted =
145  detail::convertTrackParametersToEdm4hep(gctx, Bz, trackParams);
146  setParameters(ipState, converted);
147  ipState.location = edm4hep::TrackState::AtIP;
148  ACTS_VERBOSE("Writing track level quantities as IP track state");
149  ACTS_VERBOSE("- parameters: " << track.parameters().transpose());
150  ACTS_VERBOSE(" -> " << converted.values.transpose());
151  ACTS_VERBOSE("- covariance: \n"
152  << track.covariance() << "\n->\n"
153  << converted.covariance.value());
154 
155  // Write the converted parameters to the EDM4hep track state
156  // The reference point is at the location of the reference surface of the
157  // track itself, but if that's not a perigee surface, another ad-hoc perigee
158  // at the position will be created.
159  auto center = converted.surface->center(gctx);
160  ipState.referencePoint.x = center.x();
161  ipState.referencePoint.y = center.y();
162  ipState.referencePoint.z = center.z();
163 
164  ACTS_VERBOSE("- ref surface ctr: " << center.transpose());
165 
166  for (auto& trackState : outTrackStates) {
167  to.addToTrackStates(trackState);
168  }
169 }
170 
171 template <typename track_container_t, typename track_state_container_t,
172  template <typename> class holder_t>
173 void readTrack(const edm4hep::Track& from,
174  Acts::TrackProxy<track_container_t, track_state_container_t,
175  holder_t, false>
176  track,
177  double Bz, const Logger& logger = getDummyLogger()) {
178  ACTS_VERBOSE("Reading track from EDM4hep");
179  TrackStatePropMask mask = TrackStatePropMask::Smoothed;
180 
181  std::optional<edm4hep::TrackState> ipState;
182 
183  auto unpack =
184  [](const edm4hep::TrackState& trackState) -> detail::Parameters {
185  detail::Parameters params;
186  params.covariance = ActsSquareMatrix<6>{};
187  detail::unpackCovariance(trackState.covMatrix.data(),
188  params.covariance.value());
189  params.values[0] = trackState.D0;
190  params.values[1] = trackState.Z0;
191  params.values[2] = trackState.phi;
192  params.values[3] = trackState.tanLambda;
193  params.values[4] = trackState.omega;
194  params.values[5] = trackState.time;
195 
196  Vector3 center = {
197  trackState.referencePoint.x,
198  trackState.referencePoint.y,
199  trackState.referencePoint.z,
200  };
201  params.surface = Acts::Surface::makeShared<PerigeeSurface>(center);
202 
203  return params;
204  };
205 
206  ACTS_VERBOSE("Reading " << from.trackStates_size()
207  << " track states (including IP state)");
208  // We write the trackstates out outside in, need to reverse iterate to get the
209  // same order
210  for (size_t i = from.trackStates_size() - 1; i <= from.trackStates_size();
211  i--) {
212  auto trackState = from.getTrackStates(i);
213  if (trackState.location == edm4hep::TrackState::AtIP) {
214  ipState = trackState;
215  continue;
216  }
217 
218  auto params = unpack(trackState);
219 
220  auto ts = track.appendTrackState(mask);
221  ts.typeFlags().set(MeasurementFlag);
222 
223  auto converted = detail::convertTrackParametersFromEdm4hep(Bz, params);
224 
225  ts.smoothed() = converted.parameters();
226  ts.smoothedCovariance() =
227  converted.covariance().value_or(BoundMatrix::Zero());
228  ts.setReferenceSurface(params.surface);
229  }
230 
231  if (!ipState.has_value()) {
232  ACTS_ERROR("Did not find IP state in edm4hep input");
233  throw std::runtime_error{"Did not find IP state in edm4hep input"};
234  }
235 
236  detail::Parameters params = unpack(ipState.value());
237 
238  auto converted = detail::convertTrackParametersFromEdm4hep(Bz, params);
239 
240  ACTS_VERBOSE("IP state parameters: " << converted.parameters().transpose());
241  ACTS_VERBOSE("-> covariance:\n"
242  << converted.covariance().value_or(BoundMatrix::Zero()));
243 
244  track.parameters() = converted.parameters();
245  track.covariance() = converted.covariance().value_or(BoundMatrix::Zero());
246  track.setReferenceSurface(params.surface);
247 
248  track.chi2() = from.getChi2();
249  track.nDoF() = from.getNdf();
250  track.nMeasurements() = track.nTrackStates();
251 }
252 
253 } // namespace EDM4hepUtil
254 } // namespace Acts