ATLAS Offline Software
Loading...
Searching...
No Matches
ActsToTrkConvertorAlg.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
8#include "Acts/Surfaces/Surface.hpp"
9#include "Acts/Surfaces/PerigeeSurface.hpp"
19
20// get Athena SiDetectorElement from Acts surface
21static const InDetDD::SiDetectorElement *actsToDetElem(const Acts::Surface &surface)
22{
23 const auto *actsElement = dynamic_cast<const ActsDetectorElement *>(surface.associatedDetectorElement());
24 if (!actsElement)
25 {
26 return nullptr;
27 }
28 return dynamic_cast<const InDetDD::SiDetectorElement *>(actsElement->upstreamDetectorElement());
29}
30
31namespace ActsTrk {
32
33
35 {
36 ATH_MSG_DEBUG("Initializing " << name() << " ...");
37
38 ATH_CHECK(m_tracksContainerKey.initialize());
39 ATH_CHECK(m_tracksKey.initialize());
40
43 ATH_CHECK(m_trkSummaryTool.retrieve());
44
45 if (not m_RotCreatorTool.empty())
46 {
47 ATH_MSG_DEBUG("RotCreatorTool will be used");
48 ATH_CHECK(m_RotCreatorTool.retrieve());
49 }
50
51 return StatusCode::SUCCESS;
52 }
53
54 StatusCode ActsToTrkConvertorAlg::execute(const EventContext &ctx) const
55 {
56 ATH_MSG_DEBUG("Executing " << name() << " ...");
57
58 // I/O
59 ATH_MSG_DEBUG("Retrieving input track collection '" << m_tracksContainerKey.key() << "' ...");
61 ATH_CHECK(inputTracksHandle.isValid());
62 const ActsTrk::TrackContainer *inputTracks = inputTracksHandle.cptr();
63
64 std::unique_ptr<::TrackCollection> trackCollection = std::make_unique<::TrackCollection>();
65
66 Acts::GeometryContext tgContext = m_trackingGeometryTool->getGeometryContext(ctx).context();
67 ATH_CHECK(makeTracks(ctx, tgContext, *inputTracks, *trackCollection));
68
70 ATH_MSG_DEBUG("Output Tracks Collection `" << m_tracksKey.key() << "` created ...");
71 ATH_CHECK(outputTrackHandle.record(std::move(trackCollection)));
72
73 return StatusCode::SUCCESS;
74 }
75
76 StatusCode ActsToTrkConvertorAlg::makeTracks(const EventContext &ctx,
77 const Acts::GeometryContext &tgContext,
78 const ActsTrk::TrackContainer &tracks,
79 ::TrackCollection &tracksContainer) const
80 {
81
82 for (const typename ActsTrk::TrackContainer::ConstTrackProxy track : tracks)
83 {
84 const auto lastMeasurementIndex = track.tipIndex();
85 auto finalTrajectory = std::make_unique<Trk::TrackStates>();
86 // initialise the number of dead Pixel and Acts strip
87 int numberOfDeadPixel = 0;
88 int numberOfDeadSCT = 0;
89
90 Acts::ParticleHypothesis hypothesis = track.particleHypothesis();
91
92 std::vector<std::unique_ptr<const Acts::BoundTrackParameters>> actsSmoothedParam;
93 tracks.trackStateContainer().visitBackwards(
94 lastMeasurementIndex,
95 [this, &tgContext, &track, &finalTrajectory, &actsSmoothedParam, &numberOfDeadPixel, &numberOfDeadSCT](const typename ActsTrk::TrackStateBackend::ConstTrackStateProxy &state) -> void
96 {
97 // First only consider states with an associated detector element
98 if (!state.hasReferenceSurface() || !state.referenceSurface().associatedDetectorElement())
99 {
100 return;
101 }
102
103 auto flag = state.typeFlags();
104 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typePattern;
105 std::unique_ptr<Trk::TrackParameters> parm;
106
107 // State is a hole (no associated measurement), use predicted parameters
108 if (flag.test(Acts::TrackStateFlag::HoleFlag))
109 {
110 const Acts::BoundTrackParameters actsParam = track.createParametersFromState(state);
111 parm = m_ATLASConverterTool->actsTrackParametersToTrkParameters(actsParam, tgContext);
112 auto boundaryCheck = m_boundaryCheckTool->boundaryCheck(*parm);
113
114 // Check if this is a hole, a dead sensors or a state outside the sensor boundary
115 if (boundaryCheck == Trk::BoundaryCheckResult::DeadElement)
116 {
117 auto *detElem = actsToDetElem(state.referenceSurface());
118 if (!detElem)
119 {
120 return;
121 }
122 if (detElem->isPixel())
123 {
124 ++numberOfDeadPixel;
125 }
126 else if (detElem->isSCT())
127 {
128 ++numberOfDeadSCT;
129 }
130 // Dead sensors states are not stored
131 return;
132 }
133 else if (boundaryCheck != Trk::BoundaryCheckResult::Candidate)
134 {
135 return;
136 }
137 typePattern.set(Trk::TrackStateOnSurface::Hole);
138 }
139 // The state was tagged as an outlier or (TODO!) was missed in the reverse filtering, use filtered parameters
140 else if (flag.test(Acts::TrackStateFlag::OutlierFlag))
141 {
142 const Acts::BoundTrackParameters actsParam = track.createParametersFromState(state);
143 parm = m_ATLASConverterTool->actsTrackParametersToTrkParameters(actsParam, tgContext);
144 typePattern.set(Trk::TrackStateOnSurface::Outlier);
145 }
146 // The state is a measurement state, use smoothed parameters
147 else
148 {
149 const Acts::BoundTrackParameters actsParam = track.createParametersFromState(state);
150
151 // is it really necessary to keep our own copy of all the smoothed parameters?
152 actsSmoothedParam.push_back(std::make_unique<const Acts::BoundTrackParameters>(Acts::BoundTrackParameters(actsParam)));
153 parm = m_ATLASConverterTool->actsTrackParametersToTrkParameters(actsParam, tgContext);
155 }
156
157 std::unique_ptr<Trk::MeasurementBase> measState;
158 if (state.hasUncalibratedSourceLink())
159 {
160 try {
161 auto sl = state.getUncalibratedSourceLink().template get<ATLASUncalibSourceLink>();
162 assert( sl != nullptr);
164 measState = makeRIO_OnTrack(uncalibMeas, *parm);
165 ATH_MSG_DEBUG("Successfully used ATLASUncalibratedSourceLink");
166 } catch ( const std::bad_any_cast& ){
167 ATH_MSG_DEBUG("Not an ATLASUncalibSourceLink, trying ATLASSourceLink");
168 auto sl = state.getUncalibratedSourceLink().template get<ATLASSourceLink>();
169 assert( sl != nullptr );
170 measState.reset(sl->clone());
171 ATH_MSG_DEBUG("Successfully used ATLASSourceLink");
172
173 }
174 }
175
176 double nDoF = state.calibratedSize();
177 auto quality = Trk::FitQualityOnSurface(state.chi2(), nDoF);
178 auto perState = new Trk::TrackStateOnSurface(quality,
179 std::move(measState),
180 std::move(parm),
181 nullptr,
182 typePattern);
183
184 // If a state was succesfully created add it to the trajectory
185 finalTrajectory->insert(finalTrajectory->begin(), perState);
186 });
187
188 // Convert the perigee state and add it to the trajectory
189 const Acts::BoundTrackParameters actsPer(track.referenceSurface().getSharedPtr(),
190 track.parameters(),
191 track.covariance(),
192 hypothesis);
193
194 std::unique_ptr<Trk::TrackParameters> per = m_ATLASConverterTool->actsTrackParametersToTrkParameters(actsPer, tgContext);
195 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typePattern;
196 typePattern.set(Trk::TrackStateOnSurface::Perigee);
197 auto perState = new Trk::TrackStateOnSurface(nullptr,
198 std::move(per),
199 nullptr,
200 typePattern);
201 finalTrajectory->insert(finalTrajectory->begin(), perState);
202
203 // Create the track using Athena TrackFitter::KalmanFitter and TrackPatternRecoInfo::SiSPSeededFinder algorithm enums
206
207 auto newtrack = std::make_unique<Trk::Track>(newInfo, std::move(finalTrajectory), nullptr);
208 // TODO: use TrackSummaryTool to create trackSummary?
209 if (!newtrack->trackSummary())
210 {
211 newtrack->setTrackSummary(std::make_unique<Trk::TrackSummary>());
212 newtrack->trackSummary()->update(Trk::numberOfPixelHoles, 0);
213 newtrack->trackSummary()->update(Trk::numberOfSCTHoles, 0);
214 newtrack->trackSummary()->update(Trk::numberOfTRTHoles, 0);
215 newtrack->trackSummary()->update(Trk::numberOfPixelDeadSensors, numberOfDeadPixel);
216 newtrack->trackSummary()->update(Trk::numberOfSCTDeadSensors, numberOfDeadSCT);
217 }
218
219 m_trkSummaryTool->updateTrackSummary(ctx, *newtrack, true);
220 tracksContainer.push_back(std::move(newtrack));
221 }
222
223 return StatusCode::SUCCESS;
224 }
225
226 std::unique_ptr<Trk::MeasurementBase> ActsToTrkConvertorAlg::makeRIO_OnTrack(const xAOD::UncalibratedMeasurement &uncalibMeas,
227 const Trk::TrackParameters &parm) const
228 {
229 const Trk::PrepRawData *rio = nullptr;
230 const xAOD::UncalibMeasType measurementType = uncalibMeas.type();
231
232 if (measurementType == xAOD::UncalibMeasType::PixelClusterType)
233 {
234 static const SG::AuxElement::ConstAccessor<ElementLink<InDet::PixelClusterCollection>> pixelLinkAcc("pixelClusterLink");
235 auto pixcl = dynamic_cast<const xAOD::PixelCluster *>(&uncalibMeas);
236 if (not pixcl or not pixelLinkAcc.isAvailable(*pixcl))
237 {
238 ATH_MSG_DEBUG("no pixelClusterLink for cluster associated to measurement");
239 return nullptr;
240 }
241
242 auto pix = *pixelLinkAcc(*pixcl);
243 if (m_RotCreatorTool.empty())
244 {
245 const InDetDD::SiDetectorElement *element = pix->detectorElement();
246 if (!element)
247 {
248 ATH_MSG_WARNING("Cannot access pixel detector element");
249 return nullptr;
250 }
251 ATH_MSG_DEBUG("create InDet::PixelClusterOnTrack without correction");
252 return std::make_unique<InDet::PixelClusterOnTrack>(pix,
253 Trk::LocalParameters(pix->localPosition()),
254 Amg::MatrixX(pix->localCovariance()),
255 element->identifyHash(),
256 pix->globalPosition(),
257 pix->gangedPixel(),
258 false);
259 }
260 rio = pix;
261 }
262 else if (measurementType == xAOD::UncalibMeasType::StripClusterType)
263 {
264 static const SG::AuxElement::ConstAccessor<ElementLink<InDet::SCT_ClusterCollection>> stripLinkAcc("sctClusterLink");
265 auto stripcl = dynamic_cast<const xAOD::StripCluster *>(&uncalibMeas);
266 if (not stripcl or not stripLinkAcc.isAvailable(*stripcl))
267 {
268 ATH_MSG_WARNING("no sctClusterLink for clusters associated to measurement");
269 return nullptr;
270 }
271
272 auto sct = *stripLinkAcc(*stripcl);
273 if (m_RotCreatorTool.empty())
274 {
275 const InDetDD::SiDetectorElement *element = sct->detectorElement();
276 if (!element)
277 {
278 ATH_MSG_WARNING("Cannot access strip detector element");
279 return nullptr;
280 }
281 ATH_MSG_DEBUG("create InDet::SCT_ClusterOnTrack without correction");
282 return std::make_unique<InDet::SCT_ClusterOnTrack>(sct,
283 Trk::LocalParameters(sct->localPosition()),
284 Amg::MatrixX(sct->localCovariance()),
285 element->identifyHash(),
286 sct->globalPosition(),
287 false);
288 }
289 rio = sct;
290 }
291 else
292 {
293 ATH_MSG_WARNING("xAOD::UncalibratedMeasurement is neither xAOD::PixelCluster nor xAOD::StripCluster");
294 return nullptr;
295 }
296
297 ATH_MSG_DEBUG("use Trk::RIO_OnTrackCreator::correct to create corrected Trk::RIO_OnTrack");
298 assert(!m_RotCreatorTool.empty());
299 assert(rio != nullptr);
300 return std::unique_ptr<Trk::MeasurementBase>(m_RotCreatorTool->correct(*rio, parm, Gaudi::Hive::currentContext()));
301 }
302
303}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
DataVector< Trk::Track > TrackCollection
This typedef represents a collection of Trk::Track objects.
ToolHandle< Trk::IBoundaryCheckTool > m_boundaryCheckTool
ToolHandle< ActsTrk::IActsToTrkConverterTool > m_ATLASConverterTool
ToolHandle< Trk::IExtendedTrackSummaryTool > m_trkSummaryTool
StatusCode makeTracks(const EventContext &ctx, const Acts::GeometryContext &tgContext, const ActsTrk::TrackContainer &tracks, ::TrackCollection &tracksContainer) const
virtual StatusCode initialize() override
virtual StatusCode execute(const EventContext &ctx) const override
SG::ReadHandleKey< ActsTrk::TrackContainer > m_tracksContainerKey
ToolHandle< Trk::IRIO_OnTrackCreator > m_RotCreatorTool
SG::WriteHandleKey<::TrackCollection > m_tracksKey
std::unique_ptr< Trk::MeasurementBase > makeRIO_OnTrack(const xAOD::UncalibratedMeasurement &uncalibMeas, const Trk::TrackParameters &parm) const
PublicToolHandle< ActsTrk::ITrackingGeometryTool > m_trackingGeometryTool
value_type push_back(value_type pElem)
Add an element to the end of the collection.
Class to hold geometrical description of a silicon detector element.
virtual IdentifierHash identifyHash() const override final
identifier hash (inline)
SG::ConstAccessor< T, ALLOC > ConstAccessor
Definition AuxElement.h:569
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
Contains information about the 'fitter' of this track.
@ KalmanFitter
tracks produced by the Kalman Fitter
void setPatternRecognitionInfo(const TrackPatternRecoInfo &patternReco)
Method setting the pattern recognition algorithm.
@ SiSPSeededFinder
Tracks from SiSPSeedFinder.
represents the track state (measurement, material, fit parameters and quality) at a surface.
@ Measurement
This is a measurement, and will at least contain a Trk::MeasurementBase.
@ 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 xAOD::UncalibMeasType type() const =0
Returns the type of the measurement type as a simple enumeration.
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition hcg.cxx:130
The AlignStoreProviderAlg loads the rigid alignment corrections and pipes them through the readout ge...
const xAOD::UncalibratedMeasurement & getUncalibratedMeasurement(const ATLASUncalibSourceLink &source_link)
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
@ DeadElement
outside the element
ParametersBase< TrackParametersDim, Charged > TrackParameters
@ numberOfTRTHoles
number of TRT hits which pass the high threshold (only xenon counted) total number of TRT hits which ...
@ numberOfSCTHoles
number of Holes in both sides of a SCT module
@ numberOfPixelHoles
number of pixels which have a ganged ambiguity.
@ numberOfPixelDeadSensors
number of pixel hits with broad errors (width/sqrt(12))
StripCluster_v1 StripCluster
Define the version of the strip cluster class.
PixelCluster_v1 PixelCluster
Define the version of the pixel cluster class.
UncalibMeasType
Define the type of the uncalibrated measurement.
UncalibratedMeasurement_v1 UncalibratedMeasurement
Define the version of the uncalibrated measurement class.