8#include "Acts/Seeding/EstimateTrackParamsFromSeed.hpp"
9#include "Acts/SpacePointFormation/StripSpacePointCalibration.hpp"
10#include "Acts/EventData/StripSpacePointCalibrationDetails.hpp"
11#include "Acts/EventData/TransformationHelpers.hpp"
12#include "Acts/Utilities/MathHelpers.hpp"
22template <
typename sp_range_t>
23Acts::FreeVector estimateTrackParamsFromSeed(
24 const sp_range_t& spRange,
25 const Acts::Vector3& bField,
26 const std::size_t stripCalibrationIterations) {
27 std::array<const xAOD::SpacePoint*, 3> spArray{};
28 std::array<Acts::Vector3, 3> spPositions{};
31 for (
const auto*
sp : spRange) {
33 throw std::invalid_argument(
"Empty space point found.");
35 if (i >= spArray.size()) {
36 throw std::invalid_argument(
"More than 3 space points provided.");
39 spPositions[
i] = Acts::Vector3(
sp->x(),
sp->y(),
sp->z());
42 if (i < spArray.size()) {
43 throw std::invalid_argument(
"Less than 3 space points provided.");
47 return sp->elementIdList().size() > 1;
50 std::array<Acts::Vector3, 3> spTangents{};
52 for (std::size_t i = 0;
i < stripCalibrationIterations; ++
i) {
53 Acts::estimateTrackParamsFromSeed(
54 spPositions[0], 0, spPositions[1], spPositions[2], bField,
55 &spTangents[0], &spTangents[1], &spTangents[2]);
57 for (std::size_t j = 0;
j < spArray.size(); ++
j) {
59 const bool isStrip =
sp->elementIdList().size() > 1;
64 Acts::OuterStripSpacePointCalibrationDetails calibrationDetails;
65 Eigen::Map<Eigen::Vector3f>(calibrationDetails.outerCenter.data()) =
sp->topStripCenter();
66 Eigen::Map<Eigen::Vector3f>(calibrationDetails.innerToOuterSeparation.data()) =
sp->stripCenterDistance();
67 Eigen::Map<Eigen::Vector3f>(calibrationDetails.outerHalfVector.data()) =
sp->topHalfStripLength() *
sp->topStripDirection();
68 Eigen::Map<Eigen::Vector3f>(calibrationDetails.innerHalfVector.data()) =
sp->bottomHalfStripLength() *
sp->bottomStripDirection();
69 const Acts::OuterStripSpacePointCalibrationDetailsDerived derivedCalibrationDetails =
70 Acts::deriveOuterStripSpacePointCalibrationDetails(calibrationDetails);
72 const std::optional<Eigen::Vector3f> calibratedPosition =
73 Acts::calibrateOuterStripSpacePoint(spTangents[j].cast<float>(), derivedCalibrationDetails);
74 if (!calibratedPosition.has_value()) {
77 spPositions[
j] = calibratedPosition->cast<
double>();
82 return Acts::estimateTrackParamsFromSeed(
83 spPositions[0], 0, spPositions[1], spPositions[2], bField);
89 const std::string& name,
90 const IInterface* parent)
91 : base_class(
type, name, parent)
127 return StatusCode::SUCCESS;
130 std::pair<std::optional<Acts::BoundTrackParameters>, TrackParamsEstimationTool::EstimationStatus>
134 const Acts::GeometryContext& geoContext,
135 const Acts::MagneticFieldContext& magFieldContext,
136 const Acts::CalibrationContext& calContext,
137 std::function<
const Acts::Surface&(
const ActsTrk::Seed& seed,
bool useTopSp)> retrieveSurface)
const
141 const auto& sp_collection = seed.sp();
142 if ( sp_collection.size() < 3 )
return {std::nullopt, kNoSeedRefit};
146 bottom_sp = sp_collection.at(sp_collection.size() -
m_spacePointIndicesFun(sp_collection, useTopSp)[0] - 1);
151 Acts::MagneticFieldProvider::Cache magFieldCache = magneticField.
makeCache( magFieldContext );
152 Acts::Vector3 bField = *magneticField.
getField( Acts::Vector3(bottom_sp->
x(), bottom_sp->
y(), bottom_sp->
z()),
160 const Acts::Surface& surface = retrieveSurface(seed, useTopSp);
172 std::pair<std::optional<Acts::BoundTrackParameters>, TrackParamsEstimationTool::EstimationStatus>
176 const Acts::GeometryContext& geoContext,
177 const Acts::MagneticFieldContext& magFieldContext,
178 const Acts::CalibrationContext& calContext,
179 const Acts::Surface& surface,
180 const Acts::Vector3& bField)
const
185 const auto& sp_collection = seed.sp();
186 const std::size_t nSp = sp_collection.size();
187 if (nSp < 3)
return {std::nullopt, kNoSeedRefit};
190 const auto sp_collection_extract = std::views::transform([&sp_collection, useTopSp](std::size_t i) {
191 return sp_collection.at(useTopSp ? sp_collection.size() - i - 1 : i);
198 const auto spacePointIndicesFun2 = [](std::size_t nSp) -> std::array<std::size_t, 3> {
199 return {0, nSp / 2ul, nSp - 1};
201 const Acts::FreeVector freeParams2 = estimateTrackParamsFromSeed(spacePointIndicesFun2(nSp) | sp_collection_extract, bField,
m_stripCalibrationIterations);
202 ATH_MSG_DEBUG(
"update seed p = " << 1.0 / freeParams[Acts::eFreeQOverP] <<
" to " << 1.0 / freeParams2[Acts::eFreeQOverP]);
203 freeParams[Acts::eFreeQOverP] = freeParams2[Acts::eFreeQOverP];
208 freeParams = Acts::reflectFreeParameters(freeParams);
212 Acts::BoundTrackParameters curvilinearParams = Acts::BoundTrackParameters::createCurvilinear(
213 freeParams.segment<4>(Acts::eFreePos0),
214 freeParams.segment<3>(Acts::eFreeDir0),
215 freeParams[Acts::eFreeQOverP],
217 Acts::ParticleHypothesis::pion());
220 Acts::PropagatorPlainOptions propOptions(geoContext, magFieldContext);
221 propOptions.direction = Acts::Direction::fromScalarZeroAsPositive(
224 freeParams.segment<3>(Acts::eFreePos0),
225 freeParams.segment<3>(Acts::eFreeDir0)
226 ).closest().pathLength());
228 std::optional<Acts::BoundTrackParameters> boundParams;
229 auto boundParamsResult =
230 m_extrapolator->propagateToSurface(curvilinearParams, surface, propOptions);
232 if (!boundParamsResult.ok()) {
233 ATH_MSG_DEBUG(
"Extrapolation from " << seed.sp().size() <<
"-SP seed (" << (useTopSp ?
"top" :
"bottom") <<
" start) failed - "
237 boundParams = curvilinearParams;
239 return {std::nullopt, kNoSeedRefit};
242 boundParams = *boundParamsResult;
246 Acts::EstimateTrackParamCovarianceConfig covarianceEstimationConfig = {
250 .noTimeVarInflation = 1.0,
252 boundParams->covariance() = Acts::estimateTrackParamCovariance(
253 covarianceEstimationConfig,
254 boundParams->parameters(),
258 ATH_MSG_DEBUG(
"estimateTrackParams from " << seed.sp().size() <<
"-SP seed (" << (useTopSp ?
"top" :
"bottom") <<
" start) succeeded");
259 return {boundParams, kNoSeedRefit};
262 auto refitResult =
doRefit(seed, *boundParams, geoContext, magFieldContext, calContext, reverseSearch);
263 ATH_MSG_DEBUG(
"Refit " << seed.sp().size() <<
"-SP seed (" << (reverseSearch ?
"top" :
"bottom") <<
" start) " << (refitResult ?
"succeeded" :
"failed"));
267 const auto refitErrInflation = Eigen::Map<const Acts::BoundVector>(
m_refitErrInflation.value().data());
268 refitResult->covariance()->array().colwise() *= refitErrInflation.array();
269 refitResult->covariance()->array().rowwise() *= refitErrInflation.transpose().array();
271 return {refitResult, kSeedRefitSuccess};
273 return {boundParams, kSeedRefitFailed};
284 const std::size_t nSp = spacePoints.size();
285 std::array<std::size_t, 3>
indices{};
286 std::size_t nSelected = 0;
287 double lastDistance = 0.;
288 for (std::size_t i = 0; i < nSp && nSelected <
indices.size(); ++i) {
290 const double distance = Acts::fastHypot(
sp->x(),
sp->y(),
sp->z());
291 if (nSelected > 0 && std::abs(distance - lastDistance) <= minDeltaR) {
295 lastDistance = distance;
297 if (nSelected <
indices.size()) {
299 return {0, nSp / 2ul, nSp - 1};
311 const std::size_t nSp = spacePoints.size();
313 return {0, nSp / 2ul, nSp - 1};
320 const std::size_t nSp = spacePoints.size();
322 std::size_t first = std::min(firstSp, nSp - 3ul);
323 return {first, first + 1, first + 2};
338 const Acts::BoundTrackParameters &initialParameters,
339 const Acts::GeometryContext& geometry,
340 const Acts::MagneticFieldContext& magField,
341 const Acts::CalibrationContext& calib,
342 const bool paramsAtOutermostSurface)
const {
344 const Acts::Surface* targetSurface =
nullptr;
346 if (not paramsAtOutermostSurface) {
353 if (not targetSurface) {
354 ATH_MSG_WARNING(
"Could not identify the target surface for fitting the provided seed");
357 const auto fittedSeedCollection =
m_fitterTool->fit(measurement, initialParameters,
358 geometry, magField, calib,
360 if (not fittedSeedCollection) {
364 if (fittedSeedCollection->size() != 1) {
365 ATH_MSG_WARNING(
"KF produced " << fittedSeedCollection->size() <<
" tracks but should produce 1!");
368 const auto fittedSeed = fittedSeedCollection->getTrack(0);
371 std::optional<
typename decltype(fittedSeed)::ConstTrackStateProxy> trackState {std::nullopt};
372 if (paramsAtOutermostSurface) {
373 trackState = fittedSeed.outermostTrackState();
375 trackState = fittedSeed.innermostTrackState();
378 for (
auto st : fittedSeed.trackStatesReversed()) {
386 << (paramsAtOutermostSurface ?
"outermost" :
"innermost")
392 return fittedSeed.createParametersFromState(trackState.value());
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_VERBOSE(x,...)
#define ATH_MSG_INFO(x,...)
std::vector< std::vector< int64_t > > indices
std::unique_ptr< const Acts::Logger > makeActsAthenaLogger(IMessageSvc *svc, const std::string &name, int level, std::optional< std::string > parent_name)
Acts::Result< Acts::Vector3 > getField(const Acts::Vector3 &position, Acts::MagneticFieldProvider::Cache &gcache) const override
MagneticFieldProvider::Cache makeCache(const Acts::MagneticFieldContext &mctx) const override
Helper class to access the Acts::surface associated with an Uncalibrated xAOD measurement.
The AlignStoreProviderAlg loads the rigid alignment corrections and pipes them through the readout ge...
float j(const xAOD::IParticle &, const xAOD::TrackMeasurementValidation &hit, const Eigen::Matrix3d &jab_inv)
SpacePointRange sp() const noexcept