32#include "Acts/Definitions/Units.hpp"
33#include "Acts/EventData/BoundTrackParameters.hpp"
34#include "Acts/EventData/VectorTrackContainer.hpp"
35#include "Acts/EventData/TransformationHelpers.hpp"
36#include "Acts/Geometry/TrackingGeometry.hpp"
37#include "Acts/Surfaces/detail/PlanarHelper.hpp"
40#include "Acts/EventData/TrackStatePropMask.hpp"
41#include "Acts/EventData/SourceLink.hpp"
47using namespace Acts::UnitLiterals;
53 using namespace Acts::PlanarHelper;
55 const auto isect = intersectPlane(pos, mom.normalized(), target.normal(), target.center());
57 if (inPars.covariance()) {
59 rot.block<2,2>(0,0) =
AmgSymMatrix(2){Eigen::Rotation2D{90._degree}};
60 cov = rot.transpose() * (*inPars.covariance()) * rot;
62 return target.createUniqueTrackParameters(isect.position(), mom,
63 std::copysign(1., inPars.parameters()[
Trk::qOverP]),
89 return StatusCode::SUCCESS;
92std::vector<Acts::SourceLink>
94 std::vector<Acts::SourceLink> sourceLinks{};
95 sourceLinks.reserve(track.measurementsOnTrack()->size() +
96 track.outliersOnTrack()->size());
104 const Acts::GeometryContext tgContext =
m_ctxProvider.getGeometryContext(ctx);
106 << trackColl.
size() <<
" tracks.");
107 unsigned int trkCount = 0;
108 std::vector<Identifier> failedIds;
113 auto actsTrack = outTrackcoll.getTrack(outTrackcoll.addTrack());
114 auto& trackStateContainer = outTrackcoll.trackStateContainer();
117 <<
" track states on surfaces.");
119 actsTrack.chi2() = trk->fitQuality()->chiSquared();
120 actsTrack.nDoF() = trk->fitQuality()->numberDoF();
124 bool first_tsos =
true;
125 int measurementsCount = 0;
129 Acts::TrackStatePropMask mask = Acts::TrackStatePropMask::None;
130 if (tsos->measurementOnTrack()) {
131 mask |= Acts::TrackStatePropMask::Calibrated;
133 if (tsos->trackParameters()) {
134 mask |= Acts::TrackStatePropMask::Smoothed;
138 auto index = Acts::kTrackIndexInvalid;
140 index = actsTrack.tipIndex();
142 auto actsTSOS = trackStateContainer.getTrackState(trackStateContainer.addTrackState(mask,
index));
143 ATH_MSG_VERBOSE(
"TipIndex: " << actsTrack.tipIndex() <<
" TSOS index within trajectory: "<< actsTSOS.index());
144 actsTrack.tipIndex() = actsTSOS.index();
146 if (tsos->trackParameters()) {
151 const Acts::BoundTrackParameters parameters =
m_geometryConvTool->convertTrackParametersToActs(ctx, *tsos->trackParameters());
155 failedIds.push_back(tsos->trackParameters()->associatedSurface().associatedDetectorElementIdentifier());
161 actsTrack.parameters() = parameters.parameters();
162 actsTrack.covariance() = *parameters.covariance();
163 actsTrack.setReferenceSurface(parameters.referenceSurface().getSharedPtr());
166 actsTSOS.setReferenceSurface(parameters.referenceSurface().getSharedPtr());
168 actsTSOS.smoothed() = parameters.parameters();
169 if (parameters.covariance().has_value()) {
170 actsTSOS.smoothedCovariance() = *parameters.covariance();
173 actsTSOS.smoothedCovariance() = Acts::BoundMatrix::Zero();
177 if (!(actsTSOS.hasSmoothed() && actsTSOS.hasReferenceSurface())) {
179 << actsTSOS.hasSmoothed()
180 <<
"] or reference surface ["
181 << actsTSOS.hasReferenceSurface() <<
"].");
183 ATH_MSG_VERBOSE(
"TrackState has smoothed state and reference surface.");
186 }
catch (
const std::exception& e){
187 ATH_MSG_ERROR(
"Unable to convert TrackParameter with exception ["<<e.what()<<
"]. Will be missing from ACTS track."
188 <<(*tsos->trackParameters()));
191 if (tsos->measurementOnTrack()) {
192 auto &measurement = *(tsos->measurementOnTrack());
193 actsTSOS.typeFlags().setIsMeasurement();
201 int dim = measurement.localParameters().dimension();
202 actsTSOS.allocateCalibrated(dim);
204 actsTSOS.calibrated<1>() = measurement.localParameters();
205 actsTSOS.calibratedCovariance<1>() = measurement.localCovariance();
206 }
else if (dim == 2) {
207 actsTSOS.calibrated<2>() = measurement.localParameters();
208 actsTSOS.calibratedCovariance<2>() = measurement.localCovariance();
210 throw std::domain_error(
"Cannot handle measurement dim>2");
216 actsTrack.nMeasurements() = measurementsCount;
218 <<
" track states on surfaces.");
222 if (!failedIds.empty()){
223 ATH_MSG_WARNING(
"Failed to convert "<<failedIds.size()<<
" track parameters.");
224 for (
auto id : failedIds){
228 ATH_MSG_VERBOSE(
"ACTS Track container has " << outTrackcoll.size() <<
" tracks.");
231 const Acts::BoundTrackParameters ¶meters,
233 const Acts::GeometryContext &gctx)
const {
234 auto actsPos = parameters.position(gctx);
236 if ( (actsPos - trkparameters.
position()).mag() > 0.1) {
238 << actsPos <<
" vs Trk \n"
250 const ActsTrack_t& actsTrack,
255 const ConstTrack_t& trackProxy)
const {
258template <
typename Proxy_t>
259 std::unique_ptr<Trk::Track>
261 const Proxy_t& acts_track,
264 ATH_MSG_DEBUG(__func__<<
"() "<<__LINE__<<
" - Check track "<<acts_track.tipIndex());
266 const Acts::GeometryContext tgContext{
m_ctxProvider.getGeometryContext(ctx)};
268 auto finalTrajectory = std::make_unique<Trk::TrackStates>();
272 acts_track.container().trackStateContainer().visitBackwards(acts_track.tipIndex(),
273 [&] (
const auto &state) ->
void {
274 if (!state.hasReferenceSurface()) {
284 if (!state.hasSmoothed() && !state.hasFiltered() && !state.hasPredicted()) {
285 ATH_MSG_WARNING(__func__<<
"() "<<__LINE__<<
" - State has no valid parameters (smoothed/filtered/predicted)");
290 state.referenceSurface().surfacePlacement());
291 associatedDetEl !=
nullptr) {
292 ATH_MSG_VERBOSE(
"Associated det: "<<associatedDetEl->detectorType());
295 auto flag = state.typeFlags();
297 auto boundPars = acts_track.createParametersFromState(state);
299 ATH_MSG_VERBOSE(__func__<<
"() "<<__LINE__<<
" - "<<
" hole: "<<flag.isHole()
300 <<
", outlier: "<<flag.isOutlier()<<
", measurement: "<<flag.isMeasurement()<<
"/"
302 <<
", has SL: "<<state.hasUncalibratedSourceLink()
303 <<
", parameters: "<<boundPars);
308 std::unique_ptr<Trk::TrackParameters> trkPars =
m_geometryConvTool->convertTrackParametersToTrk(ctx, boundPars);
309 std::unique_ptr<Trk::MeasurementBase> trkMeasurement{};
314 if (!m_convertHoles) { return; }
316 }
if (flag.isOutlier()) {
317 if (!m_convertOutliers) { return; }
320 if (flag.hasMeasurement()) {
321 typePattern.set(Trk::TrackStateOnSurface::Measurement);
322 nDoF = state.calibratedSize();
324 const auto slType = detail::MeasurementCalibratorBase::getType(state.getUncalibratedSourceLink());
326 using enum detail::SourceLinkType;
328 trkMeasurement = m_measCalib.unpack(state.getUncalibratedSourceLink())->uniqueClone();
331 trkMeasurement = m_prdCalib.createROT(tgContext, cctx, state.getUncalibratedSourceLink(), state);
333 case xAODUnCalibMeas:
334 appendMeasTSOS(ctx, detail::xAODUncalibMeasCalibrator::unpack(state.getUncalibratedSourceLink()),
335 typePattern, Trk::FitQualityOnSurface{chi2, nDoF},
336 std::move(trkPars), *finalTrajectory);
339 THROW_EXCEPTION(
"Invalid "<<slType<<
" type parsed.");
343 std::move(trkMeasurement),
344 std::move(trkPars),
nullptr, typePattern);
346 ATH_MSG_VERBOSE(
"State succesfully created, adding it to the trajectory");
347 finalTrajectory->insert(finalTrajectory->begin(), std::move(perState));
350 if (finalTrajectory->empty()) {
351 ATH_MSG_WARNING(__func__<<
"() "<<__LINE__<<
" No measurements added to the track");
355 std::unique_ptr<Trk::TrackParameters> per = m_geometryConvTool->convertTrackParametersToTrk(ctx, acts_track.createParametersAtReference());
356 TrkTSOSMask typePattern;
358 finalTrajectory->insert(finalTrajectory->begin(),
359 std::make_unique<Trk::TrackStateOnSurface>(
nullptr, std::move(per),
nullptr, typePattern));
361 Trk::TrackInfo newInfo{fitAuthor, ParticleHypothesis::convertTrk(acts_track.particleHypothesis())};
362 auto newtrack = std::make_unique<Trk::Track>(newInfo, std::move(finalTrajectory),
363 std::make_unique<Trk::FitQuality>(
static_cast<double>(acts_track.chi2()),
364 static_cast<int>(acts_track.nDoF())));
365 constexpr bool suppressHoleSearch =
false;
366 m_trkSummaryTool->updateTrackSummary(ctx, *newtrack, suppressHoleSearch);
371 std::unique_ptr<TrackCollection>
374 auto outColl = std::make_unique<TrackCollection>();
375 for (
const ActsTrk::TrackContainer::ConstTrackProxy trk : trackCont) {
384 std::unique_ptr<Trk::TrackParameters> trkPars,
386 std::unique_ptr<Trk::MeasurementBase> rot{};
387 switch (meas->
type()) {
389 case PixelClusterType: {
390 static const SG::AuxElement::ConstAccessor<ElementLink<InDet::PixelClusterCollection>> acc_prdLink(
"pixelClusterLink");
391 if (acc_prdLink.isAvailable(*meas) && acc_prdLink(*meas).isValid()) {
392 rot.reset(
m_ROTcreator->correct(**acc_prdLink(*meas), *trkPars, ctx));
394 ATH_MSG_WARNING(__func__<<
"() "<<__LINE__<<
" - The pixel xAOD -> prd accessor is invalid");
397 }
case StripClusterType: {
398 static const SG::AuxElement::ConstAccessor<ElementLink<InDet::SCT_ClusterCollection>> acc_prdLink(
"sctClusterLink");
399 if (acc_prdLink.isAvailable(*meas) && acc_prdLink(*meas).isValid()) {
400 rot.reset(
m_ROTcreator->correct(**acc_prdLink(*meas), *trkPars, ctx));
402 ATH_MSG_WARNING(__func__<<
"() "<<__LINE__<<
" - The strip xAOD -> prd accessor is invalid");
405 }
case MdtDriftCircleType:
406 case MMClusterType: {
411 assert(prd !=
nullptr);
416 case sTgcStripType: {
424 if (meas->
type() == RpcStripType) {
426 prd1 =
fetchPrd(ctx,
m_keyRpc, muonMeas->secondaryStrip()->identify(), modHash);
427 }
else if (meas->
type() == TgcStripType) {
429 prd1 =
fetchPrd(ctx,
m_keyTgc, muonMeas->secondaryStrip()->identify(), modHash);
432 prd1 =
fetchPrd(ctx,
m_keyStgc, muonMeas->secondaryStrip()->identify(), modHash);
434 assert(prd !=
nullptr);
435 assert(prd1 !=
nullptr);
438 const Trk::Surface& phiSurface = prd1->detectorElement()->surface(prd1->identify());
440 assert(phiPars !=
nullptr);
441 std::unique_ptr<Trk::MeasurementBase> phiRot{};
442 if (meas->
type() != sTgcStripType) {
446 phiRot.reset(
m_ROTcreator->correct(*prd1, *phiPars, ctx));
449 assert(phiRot !=
nullptr);
450 states.insert(states.begin(),
451 std::make_unique<Trk::TrackStateOnSurface>(quality,
453 std::move(phiPars),
nullptr, typePattern));
459 assert(prd !=
nullptr);
472 ATH_MSG_WARNING(__func__<<
"() "<<__LINE__<<
" - Measurement type "<<meas->
type()<<
" is not implemented");
479 assert(rot !=
nullptr);
480 assert(trkPars !=
nullptr);
481 states.insert(states.begin(),
482 std::make_unique<Trk::TrackStateOnSurface>(std::move(quality), std::move(rot),
483 std::move(trkPars),
nullptr, typePattern));
486 template <
typename PrdType_t>
491 const PrdType_t* container{
nullptr};
492 if (key.empty() || !
SG::get(container, key, ctx).isSuccess()) {
495 const auto* coll = container->indexFindPtr(hash);
496 if (coll ==
nullptr){
497 ATH_MSG_WARNING(
"fetchPrd() - Failed to find a valid collection for "<<prdId.
getString()<<
", key: "<<key.fullKey());
501 if (prd->identify() == prdId) {
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define AmgSymMatrix(dim)
DataVector< Trk::Track > TrackCollection
This typedef represents a collection of Trk::Track objects.
Extension of the interface of the Acts::SurfacePlacementBase for ATLAS.
static Acts::SourceLink pack(const Ptr_t &measurement)
Pack the measurement type pointer to an Acts::SourceLink including the intermediate conversion into a...
Class to calibrate the Acts track states with uncalibrated Trk::PrepRaw data objects.
size_type size() const noexcept
Returns the number of elements in the collection.
This is a "hash" representation of an Identifier.
std::string getString() const
Provide a string form of the identifier - hexadecimal.
Property holding a SG store/key/clid from which a ReadHandle is made.
const Amg::Vector3D & momentum() const
Access method for the momentum.
const Amg::Vector3D & position() const
Access method for the position.
virtual const Surface & associatedSurface() const override=0
Access to the Surface associated to the Parameters.
virtual const TrkDetElementBase * detectorElement() const =0
return the detector element corresponding to this PRD The pointer will be zero if the det el is not d...
Abstract Base Class for tracking surfaces.
Contains information about the 'fitter' of this track.
TrackFitter
enums to identify who created this track and what propertis does it have.
represents the track state (measurement, material, fit parameters and quality) at a surface.
@ Perigee
This represents a perigee, and so will contain a Perigee object only.
@ Outlier
This TSoS contains an outlier, that is, it contains a MeasurementBase/RIO_OnTrack which was not used ...
@ Hole
A hole on the track - this is defined in the following way.
virtual Identifier identify() const =0
Identifier.
virtual const Surface & surface() const =0
Return surface associated with this detector element.
virtual unsigned int numDimensions() const =0
Returns the number of dimensions of the measurement.
virtual xAOD::UncalibMeasType type() const =0
Returns the type of the measurement type as a simple enumeration.
double chi2(TH1 *h0, TH1 *h1)
The AlignStoreProviderAlg loads the rigid alignment corrections and pipes them through the readout ge...
Acts::TrackContainer< MutableTrackBackend, MutableTrackStateBackend, Acts::detail::ValueHolder > MutableTrackContainer
Acts::CalibrationContext getCalibrationContext(const EventContext &ctx)
The Acts::Calibration context is piped through the Acts fitters to (re)calibrate the Acts::SourceLink...
std::unique_ptr< Trk::TrackParameters > rotateParams(const Trk::TrackParameters &inPars, const Trk::Surface &target)
Eigen::Matrix< double, 3, 1 > Vector3D
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
DataVector< const Trk::TrackStateOnSurface > TrackStates
ParametersBase< TrackParametersDim, Charged > TrackParameters
UncalibratedMeasurement_v1 UncalibratedMeasurement
Define the version of the uncalibrated measurement class.
MuonMeasurement_v1 MuonMeasurement
UncalibMeasType
Define the type of the uncalibrated measurement.
CombinedMuonStrip_v1 CombinedMuonStrip
#define THROW_EXCEPTION(MESSAGE)