ATLAS Offline Software
ActsToTrkConverterTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
7 // Trk
8 #include "TrkSurfaces/Surface.h"
9 #include "TrkTrack/Track.h"
10 
11 // ATHENA
12 #include "GaudiKernel/IInterface.h"
17 #include "TrkSurfaces/Surface.h"
20 
21 // PACKAGE
28 
29 // ACTS
30 #include "Acts/Definitions/Units.hpp"
31 #include "Acts/EventData/TrackParameters.hpp"
32 #include "Acts/EventData/VectorTrackContainer.hpp"
33 #include "Acts/EventData/TransformationHelpers.hpp"
34 #include "Acts/Geometry/TrackingGeometry.hpp"
35 #include "Acts/Propagator/detail/JacobianEngine.hpp"
36 #include "Acts/Surfaces/PerigeeSurface.hpp"
37 #include "Acts/Surfaces/Surface.hpp"
39 #include "Acts/EventData/TrackStatePropMask.hpp"
40 #include "Acts/EventData/SourceLink.hpp"
42 
43 // STL
44 #include <cmath>
45 #include <iostream>
46 #include <memory>
47 #include <random>
48 
49 namespace ActsTrk {
50 
51 // Forward definitions of local functions
52 // @TODO unused, remove ?
53 #pragma GCC diagnostic push
54 #pragma GCC diagnostic ignored "-Wunused-function"
55 static void ActsMeasurementCheck(const Acts::GeometryContext &gctx,
56  const Trk::MeasurementBase &measurement,
57  const Acts::Surface &surface,
58  const Acts::BoundVector &loc);
59 #pragma GCC diagnostic pop
60 
61 static void ActsTrackParameterCheck(
62  const Acts::BoundTrackParameters &actsParameter,
63  const Acts::GeometryContext &gctx, const Acts::BoundSquareMatrix &covpc,
64  const Acts::BoundVector &targetPars, const Acts::BoundSquareMatrix &targetCov,
65  const Trk::PlaneSurface *planeSurface);
66 
67 } // namespace ActsTrk
68 
70  const std::string &type, const std::string &name, const IInterface *parent)
71  : base_class(type, name, parent) {}
72 
74  ATH_MSG_VERBOSE("Initializing ACTS to ATLAS converter tool");
75  if (m_extractMuonSurfaces){
76  ATH_CHECK(m_idHelperSvc.retrieve());
77  }
78  if (!m_trackingGeometryTool.empty()) {
79  ATH_CHECK(m_trackingGeometryTool.retrieve());
80  m_trackingGeometry = m_trackingGeometryTool->trackingGeometry();
81 
82  m_trackingGeometry->visitSurfaces([&](const Acts::Surface *surface) {
83  // find acts surface with the same detector element ID
84  if (!surface)
85  return;
86  const auto *actsElement = dynamic_cast<const ActsDetectorElement *>(
87  surface->associatedDetectorElement());
88  if (!actsElement)
89  return;
90  // Conversion from Acts to ATLAS surface impossible for the TRT so the TRT
91  // surfaces are not stored in this map
92  bool isTRT = (dynamic_cast<const InDetDD::TRT_BaseElement *>(
93  actsElement->upstreamDetectorElement()) != nullptr);
94  if (isTRT)
95  return;
96 
97  auto [it, ok] =
98  m_actsSurfaceMap.insert({actsElement->identify(), surface});
99  if (!ok) {
100  ATH_MSG_WARNING("ATLAS ID " << actsElement->identify()
101  << " has two ACTS surfaces: "
102  << it->second->geometryId() << " and "
103  << surface->geometryId());
104  }
105  });
106  }
107 
108  if (m_extractMuonSurfaces){
109  const MuonGMR4::MuonDetectorManager* muonMgr{nullptr};
110  ATH_CHECK(detStore()->retrieve(muonMgr));
111  unsigned int mapSize = m_actsSurfaceMap.size(); // For debugging message later
112  for (auto readoutElement : muonMgr->getAllReadoutElements()) {
113  std::vector<std::shared_ptr<Acts::Surface>> reSurfaces = readoutElement->getSurfaces();
114  for ( const auto& surf : reSurfaces) {
115  const Identifier id = static_cast<const ActsTrk::SurfaceCache*>(surf->associatedDetectorElement())->identify();
116  m_actsSurfaceMap.insert(std::make_pair(id, surf.get()));
117  }
118  }
119  ATH_MSG_VERBOSE("After adding muon surfaces, the map has grown from "<<mapSize<<" to "<<m_actsSurfaceMap.size());
120  }
121  return StatusCode::SUCCESS;
122 }
123 
125  const Acts::Surface &actsSurface) const {
126 
127  const auto *actsElement = dynamic_cast<const ActsDetectorElement *>(
128  actsSurface.associatedDetectorElement());
129  if (actsElement) {
130  return actsElement->atlasSurface();
131  }
132  throw std::domain_error("No ATLAS surface corresponding to to the Acts one");
133 }
134 
136  const Trk::Surface &atlasSurface) const {
137 
138  Identifier atlasID = atlasSurface.associatedDetectorElementIdentifier();
139  auto it = m_actsSurfaceMap.find(atlasID);
140  if (it != m_actsSurfaceMap.end()) {
141  return *it->second;
142  }
143  ATH_MSG_ERROR("No Acts surface corresponding to this ATLAS surface:");
144  ATH_MSG_ERROR(atlasSurface);
145  throw std::domain_error("No Acts surface corresponding to the ATLAS one");
146 }
147 
149  [[maybe_unused]] const Acts::GeometryContext& gctx,
150  const Trk::MeasurementBase &measurement) const
151 {
152  return Acts::SourceLink(&measurement);
153 }
154 
155 
156 std::vector<Acts::SourceLink>
158  const Acts::GeometryContext &gctx, const Trk::Track &track) const {
159  auto hits = track.measurementsOnTrack();
160  auto outliers = track.outliersOnTrack();
161 
162  std::vector<Acts::SourceLink> sourceLinks;
163  sourceLinks.reserve(hits->size() + outliers->size());
164 
165  for (auto it = hits->begin(); it != hits->end(); ++it) {
166  sourceLinks.push_back(trkMeasurementToSourceLink(gctx, **it));
167  }
168  for (auto it = outliers->begin(); it != outliers->end(); ++it) {
169  sourceLinks.push_back(trkMeasurementToSourceLink(gctx, **it));
170  }
171  return sourceLinks;
172 }
173 
174 
175 const Acts::BoundTrackParameters
177  const Trk::TrackParameters &atlasParameter, const Acts::GeometryContext & gctx, Trk::ParticleHypothesis hypothesis) const {
178 
179  using namespace Acts::UnitLiterals;
180  std::shared_ptr<const Acts::Surface> actsSurface;
181  Acts::BoundVector params;
182 
183  // get the associated surface
184  if (atlasParameter.hasSurface() &&
185  atlasParameter.associatedSurface().owner() == Trk::SurfaceOwner::DetElOwn) {
186  try {
187  actsSurface = trkSurfaceToActsSurface(atlasParameter.associatedSurface())
188  .getSharedPtr();
189  } catch (const std::exception &e) {
190  ATH_MSG_ERROR("Could not find ACTS detector surface for this TrackParameter:");
191  ATH_MSG_ERROR(atlasParameter);
192  throw; // Nothing we can do, so just pass exception on...
193  }
194  }
195  // no associated surface create a perigee one
196  else {
198  "trkTrackParametersToActsParameters:: No associated surface found (owner: "<<atlasParameter.associatedSurface().owner()<<
199  "). Creating a free surface. Trk parameters:");
200  ATH_MSG_VERBOSE(atlasParameter);
201 
202  switch (atlasParameter.associatedSurface().type()){
204  actsSurface = Acts::Surface::makeShared<const Acts::PlaneSurface>(
205  atlasParameter.associatedSurface().transform());
206  break;
208  actsSurface = Acts::Surface::makeShared<const Acts::PerigeeSurface>(
209  atlasParameter.associatedSurface().transform());
210  break;
211  // TODO - implement the missing types?
212  default:
213  ATH_MSG_WARNING("No surface type found for this Trk::Surface. Creating a perigee surface.");
214  actsSurface = Acts::Surface::makeShared<const Acts::PerigeeSurface>(
215  atlasParameter.associatedSurface().center());
216  }
217  }
218 
219  // Construct track parameters
220  auto atlasParam = atlasParameter.parameters();
221  if (actsSurface->bounds().type() ==
222  Acts::SurfaceBounds::BoundsType::eAnnulus) {
223  // Annulus surfaces are constructed differently in Acts/Trk so we need to
224  // convert local coordinates
225  auto position = atlasParameter.position();
226  auto result =
227  actsSurface->globalToLocal(gctx, position, atlasParameter.momentum());
228  if (result.ok()) {
229  params << (*result)[0], (*result)[1], atlasParam[Trk::phi0],
230  atlasParam[Trk::theta],
231  atlasParameter.charge() / (atlasParameter.momentum().mag() * 1_MeV),
232  0.;
233  } else {
235  "Unable to convert annulus surface - globalToLocal failed");
236  }
237  } else {
238  params << atlasParam[Trk::locX], atlasParam[Trk::locY],
239  atlasParam[Trk::phi0], atlasParam[Trk::theta],
240  atlasParameter.charge() / (atlasParameter.momentum().mag() * 1_MeV), 0.;
241  }
242 
243  Acts::BoundSquareMatrix cov = Acts::BoundSquareMatrix::Identity();
244  if (atlasParameter.covariance()) {
245  cov.topLeftCorner(5, 5) = *atlasParameter.covariance();
246 
247  // Convert the covariance matrix from MeV
248  // FIXME: This needs to handle the annulus case as well - currently the cov
249  // is wrong for annulus surfaces
250  for (int i = 0; i < cov.rows(); i++) {
251  cov(i, 4) = cov(i, 4) / 1_MeV;
252  }
253  for (int i = 0; i < cov.cols(); i++) {
254  cov(4, i) = cov(4, i) / 1_MeV;
255  }
256  }
257 
258  // convert hypotheses
260  Acts::PdgParticle absPdg = Acts::makeAbsolutePdgParticle(
261  static_cast<Acts::PdgParticle>(
262  m_pdgToParticleHypothesis.convert(hypothesis, atlasParameter.charge())));
263  Acts::ParticleHypothesis actsHypothesis{
264  absPdg, mass, Acts::AnyCharge{std::abs(static_cast<float>(atlasParameter.charge()))}};
265 
266  return Acts::BoundTrackParameters(actsSurface, params,
267  cov, actsHypothesis);
268 }
269 
270 std::unique_ptr<Trk::TrackParameters>
272  const Acts::BoundTrackParameters &actsParameter,
273  const Acts::GeometryContext &gctx) const {
274 
275  using namespace Acts::UnitLiterals;
276  std::optional<AmgSymMatrix(5)> cov = std::nullopt;
277  if (actsParameter.covariance()) {
278  AmgSymMatrix(5)
279  newcov(actsParameter.covariance()->topLeftCorner<5, 5>());
280  // Convert the covariance matrix to GeV
281  for (int i = 0; i < newcov.rows(); i++) {
282  newcov(i, 4) = newcov(i, 4) * 1_MeV;
283  }
284  for (int i = 0; i < newcov.cols(); i++) {
285  newcov(4, i) = newcov(4, i) * 1_MeV;
286  }
287  cov = std::optional<AmgSymMatrix(5)>(newcov);
288  }
289 
290  const Acts::Surface &actsSurface = actsParameter.referenceSurface();
291 
292  switch (actsSurface.type()) {
293 
295  const Trk::ConeSurface &coneSurface =
296  dynamic_cast<const Trk::ConeSurface &>(
297  actsSurfaceToTrkSurface(actsSurface));
298  return std::make_unique<Trk::AtaCone>(
299  actsParameter.get<Acts::eBoundLoc0>(),
300  actsParameter.get<Acts::eBoundLoc1>(),
301  actsParameter.get<Acts::eBoundPhi>(),
302  actsParameter.get<Acts::eBoundTheta>(),
303  actsParameter.get<Acts::eBoundQOverP>() * 1_MeV, coneSurface, cov);
304 
305  break;
306  }
308  const Trk::CylinderSurface &cylSurface =
309  dynamic_cast<const Trk::CylinderSurface &>(
310  actsSurfaceToTrkSurface(actsSurface));
311  return std::make_unique<Trk::AtaCylinder>(
312  actsParameter.get<Acts::eBoundLoc0>(),
313  actsParameter.get<Acts::eBoundLoc1>(),
314  actsParameter.get<Acts::eBoundPhi>(),
315  actsParameter.get<Acts::eBoundTheta>(),
316  actsParameter.get<Acts::eBoundQOverP>() * 1_MeV, cylSurface, cov);
317  break;
318  }
320  if (const auto *discSurface = dynamic_cast<const Trk::DiscSurface *>(
321  &actsSurfaceToTrkSurface(actsSurface));
322  discSurface != nullptr) {
323  return std::make_unique<Trk::AtaDisc>(
324  actsParameter.get<Acts::eBoundLoc0>(),
325  actsParameter.get<Acts::eBoundLoc1>(),
326  actsParameter.get<Acts::eBoundPhi>(),
327  actsParameter.get<Acts::eBoundTheta>(),
328  actsParameter.get<Acts::eBoundQOverP>() * 1_MeV, *discSurface, cov);
329  } else if (const auto *planeSurface =
330  dynamic_cast<const Trk::PlaneSurface *>(
331  &actsSurfaceToTrkSurface(actsSurface));
332  planeSurface != nullptr) {
333  // need to convert to plane position on plane surface (annulus bounds)
334  auto helperSurface = Acts::Surface::makeShared<Acts::PlaneSurface>(
335  planeSurface->transform());
336 
337  auto covpc = actsParameter.covariance().value();
338 
339  Acts::FreeVector freePars =
340  Acts::transformBoundToFreeParameters(
341  actsSurface, gctx, actsParameter.parameters());
342 
343  Acts::BoundVector targetPars =
344  Acts::transformFreeToBoundParameters(freePars,
345  *helperSurface, gctx)
346  .value();
347 
348  Acts::FreeMatrix freeTransportJacobian = Acts::FreeMatrix::Identity();
349 
350  Acts::FreeVector freeToPathDerivatives = Acts::FreeVector::Zero();
351  freeToPathDerivatives.head<3>() = freePars.segment<3>(Acts::eFreeDir0);
352 
353  auto boundToFreeJacobian = actsSurface.boundToFreeJacobian(
354  gctx, freePars.segment<3>(Acts::eFreePos0),
355  freePars.segment<3>(Acts::eFreeDir0));
356 
357  Acts::BoundMatrix boundToBoundJac = Acts::detail::boundToBoundTransportJacobian(
358  gctx, freePars, boundToFreeJacobian, freeTransportJacobian,
359  freeToPathDerivatives, *helperSurface);
360 
361  Acts::BoundMatrix targetCov =
362  boundToBoundJac * covpc * boundToBoundJac.transpose();
363 
364  auto pars = std::make_unique<Trk::AtaPlane>(
365  targetPars[Acts::eBoundLoc0], targetPars[Acts::eBoundLoc1],
366  targetPars[Acts::eBoundPhi], targetPars[Acts::eBoundTheta],
367  targetPars[Acts::eBoundQOverP] * 1_MeV, *planeSurface,
368  targetCov.topLeftCorner<5, 5>());
369 
370  if (m_visualDebugOutput) {
371  ActsTrackParameterCheck(actsParameter, gctx, covpc, targetPars,
372  targetCov, planeSurface);
373  }
374 
375  return pars;
376 
377  } else {
378  throw std::runtime_error{
379  "Acts::DiscSurface is not associated with ATLAS disc or plane "
380  "surface"};
381  }
382  break;
383  }
384  case Acts::Surface::SurfaceType::Perigee: {
385  const Trk::PerigeeSurface perSurface(actsSurface.center(gctx));
386  return std::make_unique<Trk::Perigee>(
387  actsParameter.get<Acts::eBoundLoc0>(),
388  actsParameter.get<Acts::eBoundLoc1>(),
389  actsParameter.get<Acts::eBoundPhi>(),
390  actsParameter.get<Acts::eBoundTheta>(),
391  actsParameter.get<Acts::eBoundQOverP>() * 1_MeV, perSurface, cov);
392 
393  break;
394  }
396  const Trk::PlaneSurface &plaSurface =
397  dynamic_cast<const Trk::PlaneSurface &>(
398  actsSurfaceToTrkSurface(actsSurface));
399  return std::make_unique<Trk::AtaPlane>(
400  actsParameter.get<Acts::eBoundLoc0>(),
401  actsParameter.get<Acts::eBoundLoc1>(),
402  actsParameter.get<Acts::eBoundPhi>(),
403  actsParameter.get<Acts::eBoundTheta>(),
404  actsParameter.get<Acts::eBoundQOverP>() * 1_MeV, plaSurface, cov);
405  break;
406  }
408  const Trk::StraightLineSurface &lineSurface =
409  dynamic_cast<const Trk::StraightLineSurface &>(
410  actsSurfaceToTrkSurface(actsSurface));
411  return std::make_unique<Trk::AtaStraightLine>(
412  actsParameter.get<Acts::eBoundLoc0>(),
413  actsParameter.get<Acts::eBoundLoc1>(),
414  actsParameter.get<Acts::eBoundPhi>(),
415  actsParameter.get<Acts::eBoundTheta>(),
416  actsParameter.get<Acts::eBoundQOverP>() * 1_MeV, lineSurface, cov);
417  break;
418  }
420  return std::make_unique<Trk::CurvilinearParameters>(
421  actsParameter.position(gctx), actsParameter.get<Acts::eBoundPhi>(),
422  actsParameter.get<Acts::eBoundTheta>(),
423  actsParameter.get<Acts::eBoundQOverP>() * 1_MeV, cov);
424  break;
425  }
426  case Acts::Surface::SurfaceType::Other: {
427  break;
428  }
429  }
430 
431  throw std::domain_error("Surface type not found");
432 }
433 
436  const TrackCollection &trackColl,
437  const Acts::GeometryContext & gctx) const {
438  ATH_MSG_VERBOSE("Calling trkTrackCollectionToActsTrackContainer with "
439  << trackColl.size() << " tracks.");
440  unsigned int trkCount = 0;
441  std::vector<Identifier> failedIds; // Keep track of Identifiers of failed conversions
442  for (auto trk : trackColl) {
443  // Do conversions!
444  const Trk::TrackStates *trackStates =
445  trk->trackStateOnSurfaces();
446  if (!trackStates) {
447  ATH_MSG_WARNING("No track states on surfaces found for this track.");
448  continue;
449  }
450 
451  auto actsTrack = tc.getTrack(tc.addTrack());
452  auto& trackStateContainer = tc.trackStateContainer();
453 
454  ATH_MSG_VERBOSE("Track "<<trkCount++<<" has " << trackStates->size()
455  << " track states on surfaces.");
456  // basic quantities copy
457  actsTrack.chi2() = trk->fitQuality()->chiSquared();
458  actsTrack.nDoF() = trk->fitQuality()->numberDoF();
459 
460  // loop over track states on surfaces, convert and add them to the ACTS
461  // container
462  bool first_tsos = true; // We need to handle the first one differently
463  int measurementsCount = 0;
464  for (auto tsos : *trackStates) {
465 
466  // Setup the mask
467  Acts::TrackStatePropMask mask = Acts::TrackStatePropMask::None;
468  if (tsos->measurementOnTrack()) {
469  mask |= Acts::TrackStatePropMask::Calibrated;
470  }
471  if (tsos->trackParameters()) {
472  mask |= Acts::TrackStatePropMask::Smoothed;
473  }
474 
475  // Setup the index of the trackstate
476  auto index = Acts::MultiTrajectoryTraits::kInvalid;
477  if (!first_tsos) {
478  index = actsTrack.tipIndex();
479  }
480  auto actsTSOS = trackStateContainer.getTrackState(
481  trackStateContainer.addTrackState(mask, index));
482  ATH_MSG_VERBOSE("TipIndex: " << actsTrack.tipIndex()
483  << " TSOS index within trajectory: "
484  << actsTSOS.index());
485  actsTrack.tipIndex() = actsTSOS.index();
486 
487  if (tsos->trackParameters()) {
488  // TODO This try/catch is temporary and should be removed once the sTGC problem is fixed.
489  try {
490  ATH_MSG_VERBOSE("Converting track parameters.");
491  // TODO - work out whether we should set predicted, filtered, smoothed
492  const Acts::BoundTrackParameters parameters =
493  trkTrackParametersToActsParameters(*(tsos->trackParameters()), gctx);
494  ATH_MSG_VERBOSE("Track parameters: " << parameters.parameters());
495  // Sanity check on positions
496  if (!actsTrackParameterPositionCheck(parameters, *(tsos->trackParameters()), gctx)){
497  failedIds.push_back(tsos->trackParameters()->associatedSurface().associatedDetectorElementIdentifier());
498  }
499 
500  if (first_tsos) {
501  // This is the first track state, so we need to set the track
502  // parameters
503  actsTrack.parameters() = parameters.parameters();
504  actsTrack.covariance() = *parameters.covariance();
505  actsTrack.setReferenceSurface(
506  parameters.referenceSurface().getSharedPtr());
507  first_tsos = false;
508  } else {
509  actsTSOS.setReferenceSurface(parameters.referenceSurface().getSharedPtr());
510  // Since we're converting final Trk::Tracks, let's assume they're smoothed
511  actsTSOS.smoothed() = parameters.parameters();
512  actsTSOS.smoothedCovariance() = *parameters.covariance();
513  // Not yet implemented in MultiTrajectory.icc
514  // actsTSOS.typeFlags() |= Acts::TrackStateFlag::ParameterFlag;
515  if (!(actsTSOS.hasSmoothed() && actsTSOS.hasReferenceSurface())) {
516  ATH_MSG_WARNING("TrackState does not have smoothed state ["
517  << actsTSOS.hasSmoothed()
518  << "] or reference surface ["
519  << actsTSOS.hasReferenceSurface() << "].");
520  } else {
521  ATH_MSG_VERBOSE("TrackState has smoothed state and reference surface.");
522  }
523  }
524  } catch (const std::exception& e){
525  ATH_MSG_ERROR("Unable to convert TrackParameter with exception ["<<e.what()<<"]. Will be missing from ACTS track."
526  <<(*tsos->trackParameters()));
527  }
528  }
529  if (tsos->measurementOnTrack()) {
530  auto &measurement = *(tsos->measurementOnTrack());
531 
532  measurementsCount++;
533  // const Acts::Surface &surface =
534  // trkSurfaceToActsSurface(measurement.associatedSurface());
535  // Commented for the moment because Surfaces not yet implemented in
536  // MultiTrajectory.icc
537 
538  int dim = measurement.localParameters().dimension();
539  actsTSOS.allocateCalibrated(dim);
540  if (dim == 1) {
541  actsTSOS.calibrated<1>() = measurement.localParameters();
542  actsTSOS.calibratedCovariance<1>() = measurement.localCovariance();
543  } else if (dim == 2) {
544  actsTSOS.calibrated<2>() = measurement.localParameters();
545  actsTSOS.calibratedCovariance<2>() = measurement.localCovariance();
546  } else {
547  throw std::domain_error("Cannot handle measurement dim>2");
548  }
549  actsTSOS.setUncalibratedSourceLink(Acts::SourceLink(static_cast<ActsTrk::ATLASSourceLink>(tsos->measurementOnTrack())));
550 
551  } // end if measurement
552  } // end loop over track states
553  actsTrack.nMeasurements() = measurementsCount;
554  ATH_MSG_VERBOSE("TrackProxy has " << actsTrack.nTrackStates()
555  << " track states on surfaces.");
556  }
557  ATH_MSG_VERBOSE("Finished converting " << trackColl.size() << " tracks.");
558 
559  if (!failedIds.empty()){
560  ATH_MSG_WARNING("Failed to convert "<<failedIds.size()<<" track parameters.");
561  for (auto id : failedIds){
562  ATH_MSG_WARNING("-> Failed for Identifier "<<m_idHelperSvc->toString(id));
563  }
564  }
565  ATH_MSG_VERBOSE("ACTS Track container has " << tc.size() << " tracks.");
566 }
567 
569  const Acts::BoundTrackParameters &parameters,
570  const Trk::TrackParameters &trkparameters,
571  const Acts::GeometryContext &gctx) const {
572  auto actsPos = parameters.position(gctx);
573  // ATH_MSG_VERBOSE("Acts position: \n"
574  // << actsPos << " vs trk position: \n"
575  // << trkparameters.position());
576  // ATH_MSG_VERBOSE(parameters.referenceSurface().toString(gctx));
577  // ATH_MSG_VERBOSE("GeometryId "<<parameters.referenceSurface().geometryId().value());
578 
579  if (std::fabs(actsPos.x() - trkparameters.position().x()) >
580  0.1 ||
581  std::fabs(actsPos.y() - trkparameters.position().y()) >
582  0.1 ||
583  std::fabs(actsPos.z() - trkparameters.position().z()) >
584  0.1) {
585  ATH_MSG_WARNING("Parameter position mismatch. Acts \n"
586  << actsPos << " vs Trk \n"
587  << trkparameters.position());
588  ATH_MSG_WARNING("Acts surface:");
589  ATH_MSG_WARNING(parameters.referenceSurface().toString(gctx));
590  ATH_MSG_WARNING("Trk surface:");
591  ATH_MSG_WARNING(trkparameters.associatedSurface());
592  return false;
593  }
594  return true;
595 }
596 
597 // Local functions to check/debug Annulus bounds
598 
599 #pragma GCC diagnostic push
600 #pragma GCC diagnostic ignored "-Wunused-function"
601 static void ActsTrk::ActsMeasurementCheck(
602  const Acts::GeometryContext &gctx, const Trk::MeasurementBase &measurement,
603  const Acts::Surface &surface, const Acts::BoundVector &loc) {
604  const Trk::Surface &surf = measurement.associatedSurface();
605  // only check Annulus for the moment
606  if (surf.bounds().type() != Trk::SurfaceBounds::Annulus) {
607  return;
608  }
609  const auto *bounds = dynamic_cast<const Trk::AnnulusBounds *>(&surf.bounds());
610  if (bounds == nullptr) {
611  throw std::runtime_error{"Annulus but not XY"};
612  }
613 
614  Amg::Vector2D locxy = loc.head<2>();
615 
616  Acts::ActsMatrix<2, 2> covxy = measurement.localCovariance();
617 
619  Acts::Vector2 locpc;
620  if (auto res = surface.globalToLocal(gctx, global, Acts::Vector3{});
621  res.ok()) {
622  locpc = *res;
623  } else {
624  throw std::runtime_error{"Global position not on target surface"};
625  }
626 
627  // use ACTS jacobian math to convert cluster covariance from cartesian to
628  // polar
629  auto planeSurface =
630  Acts::Surface::makeShared<Acts::PlaneSurface>(surf.transform());
631  Acts::BoundVector locxypar;
632  locxypar.head<2>() = locxy;
633  locxypar[2] = 0;
634  locxypar[3] = M_PI_2;
635  locxypar[4] = 1;
636  locxypar[5] = 1;
637  Acts::FreeVector globalxypar = Acts::transformBoundToFreeParameters(
638  *planeSurface, gctx, locxypar);
639  auto boundToFree = planeSurface->boundToFreeJacobian(
640  gctx, globalxypar.segment<3>(Acts::eFreePos0),
641  globalxypar.segment<3>(Acts::eFreeDir0));
642  Acts::ActsSquareMatrix<2> xyToXyzJac = boundToFree.topLeftCorner<2, 2>();
643 
644  Acts::BoundVector locpcpar;
645  locpcpar.head<2>() = locpc;
646  locpcpar[2] = 0;
647  locpcpar[3] = M_PI_2;
648  locpcpar[4] = 1;
649  locpcpar[5] = 1;
650  Acts::FreeVector globalpcpar = Acts::transformBoundToFreeParameters(
651  surface, gctx, locpcpar);
652 
653  boundToFree = surface.boundToFreeJacobian(
654  gctx, globalpcpar.segment<3>(Acts::eFreePos0),
655  globalpcpar.segment<3>(Acts::eFreeDir0));
656  Acts::ActsSquareMatrix<2> pcToXyzJac = boundToFree.topLeftCorner<2, 2>();
657  Acts::ActsSquareMatrix<2> xyzToPcJac = pcToXyzJac.inverse();
658 
659  // convert cluster covariance
660  Acts::ActsMatrix<2, 2> covpc = covxy;
661  covpc = xyToXyzJac * covpc * xyToXyzJac.transpose();
662  covpc = xyzToPcJac * covpc * xyzToPcJac.transpose();
663 
664  std::mt19937 gen{42 + surface.geometryId().value()};
665  std::normal_distribution<double> normal{0, 1};
666  std::uniform_real_distribution<double> uniform{-1, 1};
667 
668  Acts::ActsMatrix<2, 2> lltxy = covxy.llt().matrixL();
669  Acts::ActsMatrix<2, 2> lltpc = covpc.llt().matrixL();
670 
671  for (size_t i = 0; i < 1e4; i++) {
672  std::cout << "ANNULUS COV: ";
673  std::cout << surface.geometryId();
674 
675  Amg::Vector2D rnd{normal(gen), normal(gen)};
676 
677  // XY
678  {
679  Amg::Vector2D xy = lltxy * rnd + locxy;
680  Amg::Vector3D xyz = surf.localToGlobal(xy);
681  std::cout << "," << xy.x() << "," << xy.y();
682  std::cout << "," << xyz.x() << "," << xyz.y() << "," << xyz.z();
683  }
684  // PC
685  {
686  // Amg::Vector2D xy = lltpc * rnd + loc.head<2>();
687  Amg::Vector2D rt = lltpc * rnd + locpc;
688  Amg::Vector3D xyz = surface.localToGlobal(gctx, rt, Acts::Vector3{});
689  // Amg::Vector3D xyz = surface.transform(gctx).rotation() *
690  // Acts::Vector3{rt.x(), rt.y(), 0};
691 
692  std::cout << "," << rt.x() << "," << rt.y();
693  std::cout << "," << xyz.x() << "," << xyz.y() << "," << xyz.z();
694  }
695 
696  std::cout << std::endl;
697  }
698 }
699 #pragma GCC diagnostic pop
700 
701 void ActsTrk::ActsTrackParameterCheck(
702  const Acts::BoundTrackParameters &actsParameter,
703  const Acts::GeometryContext &gctx, const Acts::BoundSquareMatrix &covpc,
704  const Acts::BoundVector &targetPars, const Acts::BoundSquareMatrix &targetCov,
705  const Trk::PlaneSurface *planeSurface) {
706 
707  std::cout << "ANNULUS PAR COV: ";
708  std::cout << actsParameter.referenceSurface().geometryId();
709  for (unsigned int i = 0; i < 5; i++) {
710  for (unsigned int j = 0; j < 5; j++) {
711  std::cout << "," << covpc(i, j);
712  }
713  }
714  for (unsigned int i = 0; i < 5; i++) {
715  for (unsigned int j = 0; j < 5; j++) {
716  std::cout << "," << targetCov(i, j);
717  }
718  }
719  std::cout << std::endl;
720 
721  std::mt19937 gen{4242 +
722  actsParameter.referenceSurface().geometryId().value()};
723  std::normal_distribution<double> normal{0, 1};
724 
725  Acts::ActsMatrix<2, 2> lltxy =
726  targetCov.topLeftCorner<2, 2>().llt().matrixL();
727  Acts::ActsMatrix<2, 2> lltpc = covpc.topLeftCorner<2, 2>().llt().matrixL();
728 
729  for (size_t i = 0; i < 1e4; i++) {
730  std::cout << "ANNULUS PAR: ";
731  std::cout << actsParameter.referenceSurface().geometryId();
732 
733  Acts::ActsVector<2> rnd;
734  rnd << normal(gen), normal(gen);
735 
736  // XY
737  {
738  Acts::ActsVector<2> xy =
739  lltxy.topLeftCorner<2, 2>() * rnd + targetPars.head<2>();
741  planeSurface->localToGlobal(Amg::Vector2D{xy.head<2>()}, Amg::Vector3D{},
742  xyz);
743  for (unsigned int i = 0; i < 2; i++) {
744  std::cout << "," << xy[i];
745  }
746  std::cout << "," << xyz.x() << "," << xyz.y() << "," << xyz.z();
747  }
748  // PC
749  {
750  Acts::ActsVector<2> rt = lltpc.topLeftCorner<2, 2>() * rnd +
751  actsParameter.parameters().head<2>();
752  Amg::Vector3D xyz = actsParameter.referenceSurface().localToGlobal(
753  gctx, Acts::Vector2{rt.head<2>()}, Acts::Vector3{});
754 
755  for (unsigned int i = 0; i < 2; i++) {
756  std::cout << "," << rt[i];
757  }
758  std::cout << "," << xyz.x() << "," << xyz.y() << "," << xyz.z();
759  }
760 
761  std::cout << std::endl;
762  }
763 }
764 
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
make_hlt_rep.pars
pars
Definition: make_hlt_rep.py:90
UncalibratedMeasurement.h
xAOD::identify
const Identifier & identify(const UncalibratedMeasurement *meas)
Returns the associated identifier from the muon measurement.
Definition: MuonSpectrometer/MuonPhaseII/Event/xAOD/xAODMuonPrepData/Root/UtilFunctions.cxx:61
ActsToTrkConverterTool.h
yodamerge_tmp.dim
dim
Definition: yodamerge_tmp.py:239
TRTCalib_Extractor.hits
hits
Definition: TRTCalib_Extractor.py:35
get_generator_info.result
result
Definition: get_generator_info.py:21
ActsTrk::ActsToTrkConverterTool::trkTrackToSourceLinks
virtual std::vector< Acts::SourceLink > trkTrackToSourceLinks(const Acts::GeometryContext &gctx, const Trk::Track &track) const override
Transform an ATLAS track into a vector of SourceLink to be use in the avts tracking Transform both me...
Definition: ActsToTrkConverterTool.cxx:157
ActsTrk::ActsToTrkConverterTool::trkTrackParametersToActsParameters
virtual const Acts::BoundTrackParameters trkTrackParametersToActsParameters(const Trk::TrackParameters &atlasParameter, const Acts::GeometryContext &gctx, Trk::ParticleHypothesis=Trk::pion) const override
Create Acts TrackParameter from ATLAS one.
Definition: ActsToTrkConverterTool.cxx:176
MeasurementBase.h
PerigeeSurface.h
Trk::locX
@ locX
Definition: ParamDefs.h:37
Trk::ParametersBase::charge
double charge() const
Returns the charge.
Trk::locY
@ locY
local cartesian
Definition: ParamDefs.h:38
Surface.h
Trk::Track
The ATLAS Track class.
Definition: Tracking/TrkEvent/TrkTrack/TrkTrack/Track.h:73
MuonGMR4::MuonDetectorManager
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/MuonDetectorManager.h:62
SurfaceCache.h
Base_Fragment.mass
mass
Definition: Sherpa_i/share/common/Base_Fragment.py:59
ActsGeometryContext.h
Trk::PerigeeSurface
Definition: PerigeeSurface.h:43
Trk::ParametersBase::position
const Amg::Vector3D & position() const
Access method for the position.
Amg::Vector2D
Eigen::Matrix< double, 2, 1 > Vector2D
Definition: GeoPrimitives.h:48
index
Definition: index.py:1
Trk::ParametersBase::associatedSurface
virtual const Surface & associatedSurface() const override=0
Access to the Surface associated to the Parameters.
MuonGMR4::MuonReadoutElement::getSurfaces
std::vector< std::shared_ptr< Acts::Surface > > getSurfaces() const
Returns all surfaces that are associated with the active readout planes.
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/src/MuonReadoutElement.cxx:152
IdentityHelper.h
ActsTrk::ActsToTrkConverterTool::trkMeasurementToSourceLink
virtual Acts::SourceLink trkMeasurementToSourceLink(const Acts::GeometryContext &gctx, const Trk::MeasurementBase &measurement) const override
Create an SourceLink from an ATLAS measurment Works for 1 and 2D measurmenent.
Definition: ActsToTrkConverterTool.cxx:148
Trk::AnnulusBounds
Definition: AnnulusBounds.h:45
Trk::Surface::associatedDetectorElementIdentifier
Identifier associatedDetectorElementIdentifier() const
return Identifier of the associated Detector Element
python.SystemOfUnits.MeV
int MeV
Definition: SystemOfUnits.py:154
skel.it
it
Definition: skel.GENtoEVGEN.py:401
plotBeamSpotVxVal.cov
cov
Definition: plotBeamSpotVxVal.py:201
ActsTrk::ActsToTrkConverterTool::actsTrackParameterPositionCheck
bool actsTrackParameterPositionCheck(const Acts::BoundTrackParameters &actsParameter, const Trk::TrackParameters &tsos, const Acts::GeometryContext &gctx) const
Definition: ActsToTrkConverterTool.cxx:568
xyz
#define xyz
ActsTrk::SurfaceCache
: Helper class to connect the aligned transformations of each active sensor(layer) with the Acts::Sur...
Definition: Tracking/Acts/ActsGeoUtils/ActsGeoUtils/SurfaceCache.h:23
Trk::SurfaceBounds::Annulus
@ Annulus
Definition: SurfaceBounds.h:70
Trk::DiscSurface
Definition: DiscSurface.h:54
InDetDD::global
@ global
Definition: InDetDD_Defs.h:16
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
ActsTrk::ActsToTrkConverterTool::trkSurfaceToActsSurface
virtual const Acts::Surface & trkSurfaceToActsSurface(const Trk::Surface &atlasSurface) const override
Find the Acts surface corresponding to the ATLAS surface Use a map associating ATLAS ID to Acts surfa...
Definition: ActsToTrkConverterTool.cxx:135
Trk::Surface::center
const Amg::Vector3D & center() const
Returns the center position of the Surface.
AmgSymMatrix
#define AmgSymMatrix(dim)
Definition: EventPrimitives.h:50
python.CaloAddPedShiftConfig.type
type
Definition: CaloAddPedShiftConfig.py:42
python.utils.AtlRunQueryLookup.mask
string mask
Definition: AtlRunQueryLookup.py:460
master.gen
gen
Definition: master.py:32
Track.h
Trk::ParticleHypothesis
ParticleHypothesis
Definition: ParticleHypothesis.h:25
xAOD::Cone
@ Cone
Definition: TrackingPrimitives.h:553
Trk::SurfaceBounds::type
virtual BoundsType type() const =0
Return the bounds type - for persistency optimization.
CaloCellPos2Ntuple.None
None
Definition: CaloCellPos2Ntuple.py:23
Trk::Surface::owner
SurfaceOwner owner() const
return ownership
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
lumiFormat.i
int i
Definition: lumiFormat.py:85
TrackCollection
DataVector< Trk::Track > TrackCollection
This typedef represents a collection of Trk::Track objects.
Definition: TrackCollection.h:19
PixelAthClusterMonAlgCfg.e4
e4
Definition: PixelAthClusterMonAlgCfg.py:332
Trk::ParametersBase::hasSurface
virtual bool hasSurface() const override=0
Test to see if there's a not null surface ptr.
ActsTrackingGeometryTool.h
Trk::theta
@ theta
Definition: ParamDefs.h:66
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
Trk::CylinderSurface
Definition: CylinderSurface.h:55
ActsDetectorElement::atlasSurface
const Trk::Surface & atlasSurface() const
Return a shared pointer on the ATLAS surface associated with this identifier,.
Definition: ActsDetectorElement.cxx:267
calibdata.exception
exception
Definition: calibdata.py:496
res
std::pair< std::vector< unsigned int >, bool > res
Definition: JetGroupProductTest.cxx:11
MuonDetectorManager.h
test_pyathena.parent
parent
Definition: test_pyathena.py:15
xAOD::Disc
@ Disc
Definition: TrackingPrimitives.h:555
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
ActsTrk::ActsToTrkConverterTool::actsTrackParametersToTrkParameters
virtual std::unique_ptr< Trk::TrackParameters > actsTrackParametersToTrkParameters(const Acts::BoundTrackParameters &actsParameter, const Acts::GeometryContext &gctx) const override
Create ATLAS TrackParameter from Acts one.
Definition: ActsToTrkConverterTool.cxx:271
xAOD::readoutElement
const MuonGMR4::MuonReadoutElement * readoutElement(const UncalibratedMeasurement *meas)
Returns the associated readout element to the measurement.
Definition: MuonSpectrometer/MuonPhaseII/Event/xAOD/xAODMuonPrepData/Root/UtilFunctions.cxx:42
ActsDetectorElement
Definition: ActsDetectorElement.h:42
Trk::ParametersBase
Definition: ParametersBase.h:55
ActsTrk::ActsToTrkConverterTool::initialize
virtual StatusCode initialize() override
Definition: ActsToTrkConverterTool.cxx:73
ActsTrk::ActsToTrkConverterTool::ActsToTrkConverterTool
ActsToTrkConverterTool(const std::string &type, const std::string &name, const IInterface *parent)
Definition: ActsToTrkConverterTool.cxx:69
ActsDetectorElement.h
Trk::DetElOwn
@ DetElOwn
Definition: Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/Surface.h:56
DataVector< const Trk::TrackStateOnSurface >
Trk::MeasurementBase::localCovariance
const Amg::MatrixX & localCovariance() const
Interface method to get the localError.
Definition: MeasurementBase.h:138
Trk::MeasurementBase
Definition: MeasurementBase.h:58
Trk::ParticleMasses::mass
constexpr double mass[PARTICLEHYPOTHESES]
the array of masses
Definition: ParticleHypothesis.h:53
python.PyKernel.detStore
detStore
Definition: PyKernel.py:41
Trk::SurfaceType::Perigee
@ Perigee
xAOD::Straw
@ Straw
Definition: TrackingPrimitives.h:558
Trk::Surface::bounds
virtual const SurfaceBounds & bounds() const =0
Surface Bounds method.
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
Trk::MeasurementBase::associatedSurface
virtual const Surface & associatedSurface() const =0
Interface method to get the associated Surface.
xAOD::Cylinder
@ Cylinder
Definition: TrackingPrimitives.h:554
xAOD::Curvilinear
@ Curvilinear
Definition: TrackingPrimitives.h:559
SiDetectorElementCollection.h
xAOD::ParticleHypothesis
ParticleHypothesis
Definition: TrackingPrimitives.h:193
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
MultiTrajectory.h
Trk::ParametersBase::momentum
const Amg::Vector3D & momentum() const
Access method for the momentum.
H5Utils::internal::uniform
std::array< hsize_t, N > uniform(size_t val)
Definition: Writer.h:331
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
Trk::PlaneSurface
Definition: PlaneSurface.h:64
RungeKuttaUtils.h
physics_parameters.parameters
parameters
Definition: physics_parameters.py:144
Trk::ConeSurface
Definition: ConeSurface.h:51
Trk::SurfaceType::Plane
@ Plane
ActsTrk
The AlignStoreProviderAlg loads the rigid alignment corrections and pipes them through the readout ge...
Definition: MuonDetectorBuilderTool.cxx:55
ActsTrk::ActsToTrkConverterTool::trkTrackCollectionToActsTrackContainer
virtual void trkTrackCollectionToActsTrackContainer(ActsTrk::MutableTrackContainer &tc, const TrackCollection &trackColl, const Acts::GeometryContext &gctx) const override
Convert TrackCollection to Acts track container.
Definition: ActsToTrkConverterTool.cxx:434
PowhegControl_ttFCNC_NLO.params
params
Definition: PowhegControl_ttFCNC_NLO.py:226
Trk::PlaneSurface::localToGlobal
virtual void localToGlobal(const Amg::Vector2D &locp, const Amg::Vector3D &mom, Amg::Vector3D &glob) const override final
Specified for PlaneSurface: LocalToGlobal method without dynamic memory allocation.
Definition: PlaneSurface.cxx:204
xAOD::Plane
@ Plane
Definition: TrackingPrimitives.h:557
Trk::Surface
Definition: Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/Surface.h:75
ActsTrk::MutableTrackContainer
Definition: TrackContainer.h:122
Trk::Surface::transform
const Amg::Transform3D & transform() const
Returns HepGeom::Transform3D by reference.
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
Trk::Surface::type
constexpr virtual SurfaceType type() const =0
Returns the Surface type to avoid dynamic casts.
Trk::phi0
@ phi0
Definition: ParamDefs.h:65
Trk::Surface::localToGlobal
virtual void localToGlobal(const Amg::Vector2D &locp, const Amg::Vector3D &mom, Amg::Vector3D &glob) const =0
Specified by each surface type: LocalToGlobal method without dynamic memory allocation.
IActsTrackingGeometryTool.h
ActsTrk::ActsToTrkConverterTool::actsSurfaceToTrkSurface
virtual const Trk::Surface & actsSurfaceToTrkSurface(const Acts::Surface &actsSurface) const override
Find the ATLAS surface corresponding to the Acts surface Only work if the Acts surface has an associa...
Definition: ActsToTrkConverterTool.cxx:124
Trk::StraightLineSurface
Definition: StraightLineSurface.h:51
generate::Zero
void Zero(TH1D *hin)
Definition: generate.cxx:32
InDetDD::TRT_BaseElement
Definition: TRT_BaseElement.h:57
Identifier
Definition: IdentifierFieldParser.cxx:14