Take care of unit conversion between the two.
301 {
302
303 using namespace Acts::UnitLiterals;
305 if (actsParameter.covariance()) {
306 AmgSymMatrix(5) newcov(actsParameter.covariance()->topLeftCorner<5, 5>());
307
308 for (int i = 0; i < newcov.rows(); i++) {
309 newcov(i, 4) = newcov(i, 4) * 1_MeV;
310 }
311 for (
int i = 0;
i < newcov.cols();
i++) {
312 newcov(4, i) = newcov(4, i) * 1_MeV;
313 }
314 cov = std::optional<AmgSymMatrix(5)>(newcov);
315 }
316
317 const Acts::Surface &actsSurface = actsParameter.referenceSurface();
318 switch (actsSurface.type()) {
319 case Acts::Surface::SurfaceType::Cone: {
321 return std::make_unique<Trk::AtaCone>(
322 actsParameter.get<Acts::eBoundLoc0>(),
323 actsParameter.get<Acts::eBoundLoc1>(),
324 actsParameter.get<Acts::eBoundPhi>(),
325 actsParameter.get<Acts::eBoundTheta>(),
326 actsParameter.get<Acts::eBoundQOverP>() * 1_MeV, coneSurface, cov);
327 } case Acts::Surface::SurfaceType::Cylinder: {
329 return std::make_unique<Trk::AtaCylinder>(
330 actsParameter.get<Acts::eBoundLoc0>(),
331 actsParameter.get<Acts::eBoundLoc1>(),
332 actsParameter.get<Acts::eBoundPhi>(),
333 actsParameter.get<Acts::eBoundTheta>(),
334 actsParameter.get<Acts::eBoundQOverP>() * 1_MeV, cylSurface, cov);
335 } case Acts::Surface::SurfaceType::Disc: {
338 const auto& discSurface{static_cast<const Trk::DiscSurface&>(trkSurface)};
339 return std::make_unique<Trk::AtaDisc>(
340 actsParameter.get<Acts::eBoundLoc0>(),
341 actsParameter.get<Acts::eBoundLoc1>(),
342 actsParameter.get<Acts::eBoundPhi>(),
343 actsParameter.get<Acts::eBoundTheta>(),
344 actsParameter.get<Acts::eBoundQOverP>() * 1_MeV, discSurface, cov);
346 auto& planeSurface{static_cast<const Trk::PlaneSurface&>(trkSurface)};
347
348 auto helperSurface = Acts::Surface::makeShared<Acts::PlaneSurface>(planeSurface.transform());
349
350 auto covpc = actsParameter.covariance().value();
352 Acts::FreeVector freePars = Acts::transformBoundToFreeParameters(actsSurface, gctx,
353 actsParameter.parameters());
354
356 Acts::BoundVector targetPars = Acts::transformFreeToBoundParameters(freePars,
357 *helperSurface, gctx).value();
358
359 Acts::FreeMatrix freeTransportJacobian{Acts::FreeMatrix::Identity()};
360
361 Acts::FreeVector freeToPathDerivatives{Acts::FreeVector::Zero()};
362 freeToPathDerivatives.head<3>() = freePars.segment<3>(Acts::eFreeDir0);
363
364 auto boundToFreeJacobian = actsSurface.boundToFreeJacobian(gctx, freePars.segment<3>(Acts::eFreePos0),
365 freePars.segment<3>(Acts::eFreeDir0));
366
367 Acts::BoundMatrix boundToBoundJac = Acts::detail::boundToBoundTransportJacobian(gctx, freePars,
368 boundToFreeJacobian, freeTransportJacobian, freeToPathDerivatives, *helperSurface);
369
370 Acts::BoundMatrix targetCov{boundToBoundJac * covpc * boundToBoundJac.transpose()};
371
372 auto pars = std::make_unique<Trk::AtaPlane>(
373 targetPars[Acts::eBoundLoc0], targetPars[Acts::eBoundLoc1],
374 targetPars[Acts::eBoundPhi], targetPars[Acts::eBoundTheta],
375 targetPars[Acts::eBoundQOverP] * 1_MeV, planeSurface,
376 targetCov.topLeftCorner<5, 5>());
377
380 targetCov, &planeSurface);
381 }
383
384 } else {
385 throw std::domain_error("Acts::DiscSurface is not associated with ATLAS disc or plane surface");
386 }
387 break;
388 } case Acts::Surface::SurfaceType::Perigee: {
389 const Trk::PerigeeSurface perSurface(actsSurface.center(gctx));
390 return std::make_unique<Trk::Perigee>(
391 actsParameter.get<Acts::eBoundLoc0>(),
392 actsParameter.get<Acts::eBoundLoc1>(),
393 actsParameter.get<Acts::eBoundPhi>(),
394 actsParameter.get<Acts::eBoundTheta>(),
395 actsParameter.get<Acts::eBoundQOverP>() * 1_MeV, perSurface, cov);
396 } case Acts::Surface::SurfaceType::Plane: {
398 return std::make_unique<Trk::AtaPlane>(
399 actsParameter.get<Acts::eBoundLoc0>(),
400 actsParameter.get<Acts::eBoundLoc1>(),
401 actsParameter.get<Acts::eBoundPhi>(),
402 actsParameter.get<Acts::eBoundTheta>(),
403 actsParameter.get<Acts::eBoundQOverP>() * 1_MeV, plaSurface, cov);
404 } case Acts::Surface::SurfaceType::Straw: {
406 return std::make_unique<Trk::AtaStraightLine>(
407 actsParameter.get<Acts::eBoundLoc0>(),
408 actsParameter.get<Acts::eBoundLoc1>(),
409 actsParameter.get<Acts::eBoundPhi>(),
410 actsParameter.get<Acts::eBoundTheta>(),
411 actsParameter.get<Acts::eBoundQOverP>() * 1_MeV, lineSurface, cov);
412 } case Acts::Surface::SurfaceType::Curvilinear: {
413 return std::make_unique<Trk::CurvilinearParameters>(
414 actsParameter.position(gctx), actsParameter.get<Acts::eBoundPhi>(),
415 actsParameter.get<Acts::eBoundTheta>(),
416 actsParameter.get<Acts::eBoundQOverP>() * 1_MeV, cov);
417 break;
418 } case Acts::Surface::SurfaceType::Other: {
419 break;
420 }
421 }
422 throw std::domain_error("Surface type not found");
423}
#define AmgSymMatrix(dim)
virtual constexpr SurfaceType type() const =0
Returns the Surface type to avoid dynamic casts.
static void ActsTrackParameterCheck(const Acts::BoundTrackParameters &actsParameter, const Acts::GeometryContext &gctx, const Acts::BoundSquareMatrix &covpc, const Acts::BoundVector &targetPars, const Acts::BoundSquareMatrix &targetCov, const Trk::PlaneSurface *planeSurface)