From dad2af902c06141cba2ed928f09c6e3d9b6c4291 Mon Sep 17 00:00:00 2001 From: Luis Falda Coelho <56648068+LuisFelipeCoelho@users.noreply.github.com> Date: Mon, 31 Oct 2022 19:13:22 +0100 Subject: [PATCH 1/2] refactor: configurable variables in seed confirmation (#1639) This PR moves some variables related to seed confirmation from `seedFilterConfig` to `seedConfirmationRangeConfig` and makes them configurable in python --- .../Seeding/SeedConfirmationRangeConfig.hpp | 8 +++++++ Core/include/Acts/Seeding/SeedFilter.ipp | 24 ++++++++++++++++--- .../include/Acts/Seeding/SeedFilterConfig.hpp | 9 ------- Examples/Python/python/acts/examples/itk.py | 6 +++++ Examples/Python/src/TrackFinding.cpp | 3 +++ 5 files changed, 38 insertions(+), 12 deletions(-) diff --git a/Core/include/Acts/Seeding/SeedConfirmationRangeConfig.hpp b/Core/include/Acts/Seeding/SeedConfirmationRangeConfig.hpp index f443d3662ef..60c8ad3b9c1 100644 --- a/Core/include/Acts/Seeding/SeedConfirmationRangeConfig.hpp +++ b/Core/include/Acts/Seeding/SeedConfirmationRangeConfig.hpp @@ -23,11 +23,19 @@ struct SeedConfirmationRangeConfig { // compatible top required float rMaxSeedConf = std::numeric_limits::max(); // Acts::UnitConstants::mm + // number of compatible top SPs of seed if bottom radius is larger than // rMaxSeedConf size_t nTopForLargeR = 0; // number of compatible top SPs of seed if bottom radius is smaller than // rMaxSeedConf size_t nTopForSmallR = 0; + + // minimum radius for bottom SP in seed confirmation + float seedConfMinBottomRadius = 60. * Acts::UnitConstants::mm; + // maximum zOrigin in seed confirmation + float seedConfMaxZOrigin = 150. * Acts::UnitConstants::mm; + // minimum impact parameter for seed confirmation + float minImpactSeedConf = 1. * Acts::UnitConstants::mm; }; } // namespace Acts diff --git a/Core/include/Acts/Seeding/SeedFilter.ipp b/Core/include/Acts/Seeding/SeedFilter.ipp index 3fa39fa0271..b9e2e431c1c 100644 --- a/Core/include/Acts/Seeding/SeedFilter.ipp +++ b/Core/include/Acts/Seeding/SeedFilter.ipp @@ -31,6 +31,23 @@ void SeedFilter::filterSeeds_2SpFixed( std::vector>>>& outCont) const { + // seed confirmation + SeedConfirmationRangeConfig seedConfRange; + if (m_cfg.seedConfirmation) { + // check if bottom SP is in the central or forward region + seedConfRange = + (bottomSP.z() > m_cfg.centralSeedConfirmationRange.zMaxSeedConf || + bottomSP.z() < m_cfg.centralSeedConfirmationRange.zMinSeedConf) + ? m_cfg.forwardSeedConfirmationRange + : m_cfg.centralSeedConfirmationRange; + // set the minimum number of top SP depending on whether the bottom SP is + // in the central or forward region + seedFilterState.nTopSeedConf = + bottomSP.radius() > seedConfRange.rMaxSeedConf + ? seedConfRange.nTopForLargeR + : seedConfRange.nTopForSmallR; + } + size_t maxWeightSeedIndex = 0; bool maxWeightSeed = false; float weightMax = -std::numeric_limits::max(); @@ -133,10 +150,11 @@ void SeedFilter::filterSeeds_2SpFixed( (seedFilterState.numQualitySeeds and deltaSeedConf == 0)) { continue; } - bool seedRangeCuts = bottomSP.radius() < m_cfg.seedConfMinBottomRadius || - std::abs(zOrigin) > m_cfg.seedConfMaxZOrigin; + bool seedRangeCuts = + bottomSP.radius() < seedConfRange.seedConfMinBottomRadius || + std::abs(zOrigin) > seedConfRange.seedConfMaxZOrigin; if (seedRangeCuts and deltaSeedConf == 0 and - impact > m_cfg.minImpactSeedConf) { + impact > seedConfRange.minImpactSeedConf) { continue; } diff --git a/Core/include/Acts/Seeding/SeedFilterConfig.hpp b/Core/include/Acts/Seeding/SeedFilterConfig.hpp index ee772c2b3dc..5812b7c2915 100644 --- a/Core/include/Acts/Seeding/SeedFilterConfig.hpp +++ b/Core/include/Acts/Seeding/SeedFilterConfig.hpp @@ -53,12 +53,6 @@ struct SeedFilterConfig { SeedConfirmationRangeConfig centralSeedConfirmationRange; // contains parameters for forward seed confirmation SeedConfirmationRangeConfig forwardSeedConfirmationRange; - // minimum radius for bottom SP in seed confirmation - float seedConfMinBottomRadius = 60. * Acts::UnitConstants::mm; - // maximum zOrigin in seed confirmation - float seedConfMaxZOrigin = 150. * Acts::UnitConstants::mm; - // minimum impact parameter for seed confirmation - float minImpactSeedConf = 1. * Acts::UnitConstants::mm; // maximum number of lower quality seeds in seed confirmation int maxSeedsPerSpMConf = std::numeric_limits::max(); @@ -76,9 +70,6 @@ struct SeedFilterConfig { SeedFilterConfig config = *this; config.deltaRMin /= 1_mm; config.deltaInvHelixDiameter /= 1. / 1_mm; - config.seedConfMinBottomRadius /= 1_mm; - config.seedConfMaxZOrigin /= 1_mm; - config.minImpactSeedConf /= 1_mm; return config; } diff --git a/Examples/Python/python/acts/examples/itk.py b/Examples/Python/python/acts/examples/itk.py index 3c40cfd063d..0735dc43f69 100644 --- a/Examples/Python/python/acts/examples/itk.py +++ b/Examples/Python/python/acts/examples/itk.py @@ -314,6 +314,9 @@ def itkSeedingAlgConfig(inputSpacePointsType): rMaxSeedConf=140 * u.mm, nTopForLargeR=1, nTopForSmallR=2, + seedConfMinBottomRadius=60.0 * u.mm, + seedConfMaxZOrigin=150.0 * u.mm, + minImpactSeedConf=1.0 * u.mm, ) # contains parameters for seed confirmation forwardSeedConfirmationRange = acts.SeedConfirmationRangeConfig( zMinSeedConf=-3000 * u.mm, @@ -321,6 +324,9 @@ def itkSeedingAlgConfig(inputSpacePointsType): rMaxSeedConf=140 * u.mm, nTopForLargeR=1, nTopForSmallR=2, + seedConfMinBottomRadius=60.0 * u.mm, + seedConfMaxZOrigin=150.0 * u.mm, + minImpactSeedConf=1.0 * u.mm, ) compatSeedWeight = 100 curvatureSortingInFilter = True diff --git a/Examples/Python/src/TrackFinding.cpp b/Examples/Python/src/TrackFinding.cpp index 90e32c7f260..23368c8de44 100644 --- a/Examples/Python/src/TrackFinding.cpp +++ b/Examples/Python/src/TrackFinding.cpp @@ -129,6 +129,9 @@ void addTrackFinding(Context& ctx) { ACTS_PYTHON_MEMBER(rMaxSeedConf); ACTS_PYTHON_MEMBER(nTopForLargeR); ACTS_PYTHON_MEMBER(nTopForSmallR); + ACTS_PYTHON_MEMBER(seedConfMinBottomRadius); + ACTS_PYTHON_MEMBER(seedConfMaxZOrigin); + ACTS_PYTHON_MEMBER(minImpactSeedConf); ACTS_PYTHON_STRUCT_END(); patchKwargsConstructor(c); } From ec15a62d13b87ad40c200af5d9a6efbf8f39492a Mon Sep 17 00:00:00 2001 From: Benjamin Huth <37871400+benjaminhuth@users.noreply.github.com> Date: Tue, 1 Nov 2022 14:41:46 +0100 Subject: [PATCH 2/2] refactor!: std::unique_ptr to std::optional in Acts::PropagatorResult (#1622) This changes the type that stores the parameters and covariance matrix in the `Acts::PropagatorResult`. I'm not sure why we have `std::unique_ptr` here, maybe this is from pre-C++17 where `std::optional` was not available? However, both from usibility (not copy-able) and from performance perspective (heap allocation) this does not make sense to me, but maybe I forget something... --- Core/include/Acts/Propagator/Propagator.hpp | 8 ++-- Core/include/Acts/Propagator/Propagator.ipp | 16 ++------ .../Acts/TrackFitting/GaussianSumFitter.hpp | 2 +- .../Vertexing/AdaptiveMultiVertexFitter.ipp | 6 +-- .../Acts/Vertexing/HelicalTrackLinearizer.ipp | 17 ++++----- .../Acts/Vertexing/ImpactPointEstimator.hpp | 9 ++--- .../Acts/Vertexing/ImpactPointEstimator.ipp | 4 +- .../Core/Propagator/ExtrapolatorTests.cpp | 6 +-- .../Propagator/MaterialCollectionTests.cpp | 38 +++++++++---------- .../Vertexing/ImpactPointEstimatorTests.cpp | 4 +- 10 files changed, 49 insertions(+), 61 deletions(-) diff --git a/Core/include/Acts/Propagator/Propagator.hpp b/Core/include/Acts/Propagator/Propagator.hpp index ec80eaf6855..7b9517cb230 100644 --- a/Core/include/Acts/Propagator/Propagator.hpp +++ b/Core/include/Acts/Propagator/Propagator.hpp @@ -29,7 +29,7 @@ #include #include -#include +#include #include #include @@ -46,11 +46,11 @@ struct PropagatorResult : private detail::Extendable { /// Accessor to additional propagation quantities using detail::Extendable::get; - /// Final track parameters - initialized to null pointer - std::unique_ptr endParameters = nullptr; + /// Final track parameters + std::optional endParameters = std::nullopt; /// Full transport jacobian - std::unique_ptr transportJacobian = nullptr; + std::optional transportJacobian = std::nullopt; /// Number of propagation steps that were carried out unsigned int steps = 0; diff --git a/Core/include/Acts/Propagator/Propagator.ipp b/Core/include/Acts/Propagator/Propagator.ipp index 0a52f3015d4..2f1c0727155 100644 --- a/Core/include/Acts/Propagator/Propagator.ipp +++ b/Core/include/Acts/Propagator/Propagator.ipp @@ -160,15 +160,11 @@ auto Acts::Propagator::propagate( if (result.ok()) { /// Convert into return type and fill the result object auto curvState = m_stepper.curvilinearState(state.stepping); - auto& curvParameters = std::get(curvState); // Fill the end parameters - inputResult.endParameters = - std::make_unique(std::move(curvParameters)); + inputResult.endParameters = std::get(curvState); // Only fill the transport jacobian when covariance transport was done if (state.stepping.covTransport) { - auto& tJacobian = std::get(curvState); - inputResult.transportJacobian = - std::make_unique(std::move(tJacobian)); + inputResult.transportJacobian = std::get(curvState); } return Result::success(std::forward(inputResult)); } else { @@ -258,15 +254,11 @@ auto Acts::Propagator::propagate( const auto& bs = *bsRes; - auto& boundParams = std::get(bs); // Fill the end parameters - inputResult.endParameters = - std::make_unique(std::move(boundParams)); + inputResult.endParameters = std::get(bs); // Only fill the transport jacobian when covariance transport was done if (state.stepping.covTransport) { - auto& tJacobian = std::get(bs); - inputResult.transportJacobian = - std::make_unique(std::move(tJacobian)); + inputResult.transportJacobian = std::get(bs); } return Result::success(std::forward(inputResult)); } else { diff --git a/Core/include/Acts/TrackFitting/GaussianSumFitter.hpp b/Core/include/Acts/TrackFitting/GaussianSumFitter.hpp index be851075f31..f2661b86817 100644 --- a/Core/include/Acts/TrackFitting/GaussianSumFitter.hpp +++ b/Core/include/Acts/TrackFitting/GaussianSumFitter.hpp @@ -474,7 +474,7 @@ struct GaussianSumFitter { ACTS_VERBOSE("+-----------------------------------------------+"); ACTS_VERBOSE("| Gsf: Do propagation back to reference surface |"); ACTS_VERBOSE("+-----------------------------------------------+"); - auto lastResult = [&]() -> Result> { + auto lastResult = [&]() -> Result> { const auto& [surface, lastSmoothedState] = std::get<1>(smoothResult).front(); diff --git a/Core/include/Acts/Vertexing/AdaptiveMultiVertexFitter.ipp b/Core/include/Acts/Vertexing/AdaptiveMultiVertexFitter.ipp index 556f7497544..7aa13de8623 100644 --- a/Core/include/Acts/Vertexing/AdaptiveMultiVertexFitter.ipp +++ b/Core/include/Acts/Vertexing/AdaptiveMultiVertexFitter.ipp @@ -206,7 +206,7 @@ Acts::Result Acts:: return res.error(); } // Set ip3dParams for current trackAtVertex - currentVtxInfo.ip3dParams.emplace(trk, *(res.value())); + currentVtxInfo.ip3dParams.emplace(trk, res.value()); } return {}; } @@ -236,7 +236,7 @@ Acts::AdaptiveMultiVertexFitter:: return res.error(); } // Set ip3dParams for current trackAtVertex - currentVtxInfo.ip3dParams.emplace(trk, *(res.value())); + currentVtxInfo.ip3dParams.emplace(trk, res.value()); } // Set compatibility with current vertex auto compRes = m_cfg.ipEst.get3dVertexCompatibility( @@ -342,4 +342,4 @@ void Acts::AdaptiveMultiVertexFitter< } } } -} \ No newline at end of file +} diff --git a/Core/include/Acts/Vertexing/HelicalTrackLinearizer.ipp b/Core/include/Acts/Vertexing/HelicalTrackLinearizer.ipp index b89e286e4e8..f6a29f41096 100644 --- a/Core/include/Acts/Vertexing/HelicalTrackLinearizer.ipp +++ b/Core/include/Acts/Vertexing/HelicalTrackLinearizer.ipp @@ -29,30 +29,29 @@ Acts::Result Acts:: ? NavigationDirection::Forward : NavigationDirection::Backward; - const BoundTrackParameters* endParams = nullptr; // Do the propagation to linPointPos auto result = m_cfg.propagator->propagate(params, *perigeeSurface, pOptions); - if (result.ok()) { - endParams = (*result).endParameters.get(); - } else { + if (not result.ok()) { return result.error(); } - BoundVector paramsAtPCA = endParams->parameters(); + const auto& endParams = *result->endParameters; + + BoundVector paramsAtPCA = endParams.parameters(); Vector4 positionAtPCA = Vector4::Zero(); { - auto pos = endParams->position(gctx); + auto pos = endParams.position(gctx); positionAtPCA[ePos0] = pos[ePos0]; positionAtPCA[ePos1] = pos[ePos1]; positionAtPCA[ePos2] = pos[ePos2]; - positionAtPCA[eTime] = endParams->time(); + positionAtPCA[eTime] = endParams.time(); } - BoundSymMatrix parCovarianceAtPCA = endParams->covariance().value(); + BoundSymMatrix parCovarianceAtPCA = endParams.covariance().value(); if (parCovarianceAtPCA.determinant() <= 0) { // Use the original parameters paramsAtPCA = params.parameters(); - auto pos = endParams->position(gctx); + auto pos = endParams.position(gctx); positionAtPCA[ePos0] = pos[ePos0]; positionAtPCA[ePos1] = pos[ePos1]; positionAtPCA[ePos2] = pos[ePos2]; diff --git a/Core/include/Acts/Vertexing/ImpactPointEstimator.hpp b/Core/include/Acts/Vertexing/ImpactPointEstimator.hpp index cc3523b431e..e6334c73c85 100644 --- a/Core/include/Acts/Vertexing/ImpactPointEstimator.hpp +++ b/Core/include/Acts/Vertexing/ImpactPointEstimator.hpp @@ -112,11 +112,10 @@ class ImpactPointEstimator { /// @param state The state object /// /// @return New track params - Result> - estimate3DImpactParameters(const GeometryContext& gctx, - const Acts::MagneticFieldContext& mctx, - const BoundTrackParameters& trkParams, - const Vector3& vtxPos, State& state) const; + Result estimate3DImpactParameters( + const GeometryContext& gctx, const Acts::MagneticFieldContext& mctx, + const BoundTrackParameters& trkParams, const Vector3& vtxPos, + State& state) const; /// @brief Estimates the compatibility of a /// track to a vertex position based on the 3d diff --git a/Core/include/Acts/Vertexing/ImpactPointEstimator.ipp b/Core/include/Acts/Vertexing/ImpactPointEstimator.ipp index bbb3c1fad6b..de7c6fbb382 100644 --- a/Core/include/Acts/Vertexing/ImpactPointEstimator.ipp +++ b/Core/include/Acts/Vertexing/ImpactPointEstimator.ipp @@ -35,7 +35,7 @@ Acts::ImpactPointEstimator:: template -Acts::Result> +Acts::Result Acts::ImpactPointEstimator:: estimate3DImpactParameters(const GeometryContext& gctx, const Acts::MagneticFieldContext& mctx, @@ -79,7 +79,7 @@ Acts::ImpactPointEstimator:: // Do the propagation to linPointPos auto result = m_cfg.propagator->propagate(trkParams, *planeSurface, pOptions); if (result.ok()) { - return std::move((*result).endParameters); + return *result->endParameters; } else { return result.error(); } diff --git a/Tests/UnitTests/Core/Propagator/ExtrapolatorTests.cpp b/Tests/UnitTests/Core/Propagator/ExtrapolatorTests.cpp index 1ea13552468..3fe2ae8476b 100644 --- a/Tests/UnitTests/Core/Propagator/ExtrapolatorTests.cpp +++ b/Tests/UnitTests/Core/Propagator/ExtrapolatorTests.cpp @@ -109,8 +109,8 @@ BOOST_DATA_TEST_CASE( options.maxStepSize = 10_cm; options.pathLimit = 25_cm; - BOOST_CHECK(epropagator.propagate(start, options).value().endParameters != - nullptr); + BOOST_CHECK( + epropagator.propagate(start, options).value().endParameters.has_value()); } // This test case checks that no segmentation fault appears @@ -176,7 +176,7 @@ BOOST_DATA_TEST_CASE( const auto& cresult = epropagator.propagate(start, *csurface, optionsEmpty) .value() .endParameters; - BOOST_CHECK(cresult != nullptr); + BOOST_CHECK(cresult.has_value()); } } diff --git a/Tests/UnitTests/Core/Propagator/MaterialCollectionTests.cpp b/Tests/UnitTests/Core/Propagator/MaterialCollectionTests.cpp index 96c72602dbf..122392a17e7 100644 --- a/Tests/UnitTests/Core/Propagator/MaterialCollectionTests.cpp +++ b/Tests/UnitTests/Core/Propagator/MaterialCollectionTests.cpp @@ -172,7 +172,7 @@ void runTest(const propagator_t& prop, double pT, double phi, double theta, std::cout << ">>> Backward Propagation : start." << std::endl; } const auto& bwdResult = - prop.propagate(*fwdResult.endParameters.get(), startSurface, bwdOptions) + prop.propagate(*fwdResult.endParameters, startSurface, bwdOptions) .value(); if (debugModeBwd) { @@ -241,18 +241,18 @@ void runTest(const propagator_t& prop, double pT, double phi, double theta, } // move forward step by step through the surfaces - const BoundTrackParameters* sParameters = &start; - std::vector> stepParameters; + BoundTrackParameters sParameters = start; + std::vector stepParameters; for (auto& fwdSteps : fwdMaterial.materialInteractions) { if (debugModeFwdStep) { std::cout << ">>> Forward step : " - << sParameters->referenceSurface().geometryId() << " --> " + << sParameters.referenceSurface().geometryId() << " --> " << fwdSteps.surface->geometryId() << std::endl; } // make a forward step const auto& fwdStep = - prop.propagate(*sParameters, (*fwdSteps.surface), fwdStepOptions) + prop.propagate(sParameters, (*fwdSteps.surface), fwdStepOptions) .value(); auto& fwdStepMaterial = @@ -260,11 +260,10 @@ void runTest(const propagator_t& prop, double pT, double phi, double theta, fwdStepStepMaterialInX0 += fwdStepMaterial.materialInX0; fwdStepStepMaterialInL0 += fwdStepMaterial.materialInL0; - if (fwdStep.endParameters != nullptr) { + if (fwdStep.endParameters.has_value()) { // make sure the parameters do not run out of scope - stepParameters.push_back(std::make_unique( - (*fwdStep.endParameters.get()))); - sParameters = stepParameters.back().get(); + stepParameters.push_back(*fwdStep.endParameters); + sParameters = stepParameters.back(); } } // final destination surface @@ -272,12 +271,12 @@ void runTest(const propagator_t& prop, double pT, double phi, double theta, if (debugModeFwdStep) { std::cout << ">>> Forward step : " - << sParameters->referenceSurface().geometryId() << " --> " + << sParameters.referenceSurface().geometryId() << " --> " << dSurface.geometryId() << std::endl; } const auto& fwdStepFinal = - prop.propagate(*sParameters, dSurface, fwdStepOptions).value(); + prop.propagate(sParameters, dSurface, fwdStepOptions).value(); auto& fwdStepMaterial = fwdStepFinal.template get(); @@ -317,16 +316,16 @@ void runTest(const propagator_t& prop, double pT, double phi, double theta, } // move forward step by step through the surfaces - sParameters = fwdResult.endParameters.get(); + sParameters = *fwdResult.endParameters; for (auto& bwdSteps : bwdMaterial.materialInteractions) { if (debugModeBwdStep) { std::cout << ">>> Backward step : " - << sParameters->referenceSurface().geometryId() << " --> " + << sParameters.referenceSurface().geometryId() << " --> " << bwdSteps.surface->geometryId() << std::endl; } // make a forward step const auto& bwdStep = - prop.propagate(*sParameters, (*bwdSteps.surface), bwdStepOptions) + prop.propagate(sParameters, (*bwdSteps.surface), bwdStepOptions) .value(); auto& bwdStepMaterial = @@ -334,11 +333,10 @@ void runTest(const propagator_t& prop, double pT, double phi, double theta, bwdStepStepMaterialInX0 += bwdStepMaterial.materialInX0; bwdStepStepMaterialInL0 += bwdStepMaterial.materialInL0; - if (bwdStep.endParameters != nullptr) { + if (bwdStep.endParameters.has_value()) { // make sure the parameters do not run out of scope - stepParameters.push_back(std::make_unique( - *(bwdStep.endParameters.get()))); - sParameters = stepParameters.back().get(); + stepParameters.push_back(*bwdStep.endParameters); + sParameters = stepParameters.back(); } } // final destination surface @@ -346,12 +344,12 @@ void runTest(const propagator_t& prop, double pT, double phi, double theta, if (debugModeBwdStep) { std::cout << ">>> Backward step : " - << sParameters->referenceSurface().geometryId() << " --> " + << sParameters.referenceSurface().geometryId() << " --> " << dSurface.geometryId() << std::endl; } const auto& bwdStepFinal = - prop.propagate(*sParameters, dbSurface, bwdStepOptions).value(); + prop.propagate(sParameters, dbSurface, bwdStepOptions).value(); auto& bwdStepMaterial = bwdStepFinal.template get(); diff --git a/Tests/UnitTests/Core/Vertexing/ImpactPointEstimatorTests.cpp b/Tests/UnitTests/Core/Vertexing/ImpactPointEstimatorTests.cpp index 0d24a3e7a52..8a9b40b6621 100644 --- a/Tests/UnitTests/Core/Vertexing/ImpactPointEstimatorTests.cpp +++ b/Tests/UnitTests/Core/Vertexing/ImpactPointEstimatorTests.cpp @@ -134,7 +134,7 @@ BOOST_DATA_TEST_CASE(SingleTrackDistanceParametersCompatibility3d, tracks, d0, // estimate parameters at the closest point in 3d auto res = ipEstimator.estimate3DImpactParameters( geoContext, magFieldContext, myTrack, refPosition, state); - BoundTrackParameters trackAtIP3d = **res; + BoundTrackParameters trackAtIP3d = *res; const auto& atPerigee = myTrack.parameters(); const auto& atIp3d = trackAtIP3d.parameters(); @@ -190,7 +190,7 @@ BOOST_AUTO_TEST_CASE(SingleTrackDistanceParametersAthenaRegression) { auto res2 = ipEstimator.estimate3DImpactParameters( geoContext, magFieldContext, params1, vtxPos, state); BOOST_CHECK(res2.ok()); - BoundTrackParameters endParams = **res2; + BoundTrackParameters endParams = *res2; Vector3 surfaceCenter = endParams.referenceSurface().center(geoContext); BOOST_CHECK_EQUAL(surfaceCenter, vtxPos);