ATLAS Offline Software
Loading...
Searching...
No Matches
GNNSeedingTrackMaker.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
7#include <algorithm>
8#include <fstream>
9#include <memory>
10#include <unordered_set>
11
14
16 ISvcLocator* pSvcLocator)
17 : AthReentrantAlgorithm(name, pSvcLocator) {}
18
20 ATH_CHECK(m_SpacePointsPixelKey.initialize());
21 ATH_CHECK(m_SpacePointsStripKey.initialize());
22
23 ATH_CHECK(m_pixelClusterKey.initialize());
24 ATH_CHECK(m_stripClusterKey.initialize());
25 ATH_CHECK(m_boundaryPixelKey.initialize());
26 ATH_CHECK(m_boundaryStripKey.initialize());
27
31
32 ATH_CHECK(m_outputTracksKey.initialize());
33
34 ATH_CHECK(m_seedFitter.retrieve());
35 ATH_CHECK(m_trackFitter.retrieve());
36 ATH_CHECK(m_roadmaker.retrieve());
37
38 ATH_CHECK(m_proptool.retrieve());
39 ATH_CHECK(m_updatortool.retrieve());
40 ATH_CHECK(m_riocreator.retrieve());
41
42 ATH_CHECK(m_pixelCondSummaryTool.retrieve(DisableTool{
43 (!m_pixelDetElStatus.empty() && !VALIDATE_STATUS_ARRAY_ACTIVATED)}));
44 ATH_CHECK(m_stripCondSummaryTool.retrieve(DisableTool{
45 (!m_stripDetElStatus.empty() && !VALIDATE_STATUS_ARRAY_ACTIVATED)}));
47
49
50 if (!m_gnnTrackFinder.empty() && !m_gnnTrackReader.empty()) {
51 ATH_MSG_ERROR("Use either track finder or track reader, not both.");
52 return StatusCode::FAILURE;
53 }
54
55 if (!m_gnnTrackFinder.empty()) {
56 ATH_MSG_INFO("Use GNN Track Finder");
57 ATH_CHECK(m_gnnTrackFinder.retrieve());
58 }
59 if (!m_gnnTrackReader.empty()) {
60 ATH_MSG_INFO("Use GNN Track Reader");
61 ATH_CHECK(m_gnnTrackReader.retrieve());
62 }
63
64 return StatusCode::SUCCESS;
65}
66
77
78StatusCode InDet::GNNSeedingTrackMaker::execute(const EventContext& ctx) const {
80 ATH_CHECK(outputTracks.record(std::make_unique<TrackCollection>()));
81
82 // get event info
83 uint32_t runNumber = ctx.eventID().run_number();
84 uint32_t eventNumber = ctx.eventID().event_number();
85
86 std::vector<const Trk::SpacePoint*> spacePoints;
87
88 auto getSpacepointData =
89 [&](const SG::ReadHandleKey<SpacePointContainer>& containerKey) {
90 if (not containerKey.empty()) {
91
92 SG::ReadHandle<SpacePointContainer> container{containerKey, ctx};
93
94 if (container.isValid()) {
95 for (auto spCollection : *container.cptr()) {
96 for (const Trk::SpacePoint* spacepoint : *spCollection) {
97 spacePoints.push_back(spacepoint);
98 }
99 }
100 }
101 }
102 };
103
104 getSpacepointData(m_SpacePointsPixelKey);
105 getSpacepointData(m_SpacePointsStripKey);
106
108 ctx};
110 ctx};
111 ATH_MSG_DEBUG("Found " << pixelClusters->size() << " pixel clusters");
112 ATH_MSG_DEBUG("Found " << stripClusters->size() << " strip clusters");
113 ATH_MSG_DEBUG("Found " << spacePoints.size() << " space points");
114
115 std::vector<std::vector<uint32_t>> gnnTrackCandidates;
116 if (m_gnnTrackFinder.isSet()) {
117 ATH_CHECK(m_gnnTrackFinder->getTracks(spacePoints, gnnTrackCandidates));
118 } else if (m_gnnTrackReader.isSet()) {
119 m_gnnTrackReader->getTracks(runNumber, eventNumber, gnnTrackCandidates);
120 } else {
121 ATH_MSG_ERROR("Both GNNTrackFinder and GNNTrackReader are not set");
122 return StatusCode::FAILURE;
123 }
124
125 ATH_MSG_DEBUG("Obtained " << gnnTrackCandidates.size() << " Tracks");
126
127 // loop over all track candidates
128 // and perform track fitting for each.
129 //Local variable data uses 813712 bytes
130 //coverity[STACK_USE]
132 if (not data.isInitialized())
134 // Erase statistic information
135 //
136 data.inputseeds() = 0;
137 data.goodseeds() = 0;
138 data.inittracks() = 0;
139 data.findtracks() = 0;
140 data.roadbug() = 0;
141 // Set track info
142 //
143 data.trackinfo().setPatternRecognitionInfo(Trk::TrackInfo::SiSPSeededFinder);
144 data.setCosmicTrack(0);
145 data.setPixContainer(pixelClusters.cptr());
146 data.setSctContainer(stripClusters.cptr());
147
149
150 // Get AtlasFieldCache
151 MagField::AtlasFieldCache fieldCache;
152
155 ctx};
156 const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
157 if (fieldCondObj == nullptr) {
159 "InDet::SiTrackMaker_xk::getTracks: Failed to retrieve "
160 "AtlasFieldCacheCondObj with key "
161 << m_fieldCondObjInputKey.key());
162 return StatusCode::FAILURE;
163 }
164 fieldCondObj->getInitializedCache(fieldCache);
165
166 int num_extended_tracks = 0;
167
168 for (auto& trackIndices : gnnTrackCandidates) {
169
170 std::vector<const Trk::PrepRawData*> clusters; // only pixel clusters!
171 std::vector<const Trk::SpacePoint*> trackCandidate;
172 trackCandidate.reserve(trackIndices.size());
173
174 for (auto& id : trackIndices) {
176 if (id > spacePoints.size()) {
177 ATH_MSG_WARNING("SpacePoint index out of range");
178 continue;
179 }
180 const Trk::SpacePoint* sp = spacePoints[id];
181 if (sp != nullptr) {
182 trackCandidate.push_back(sp);
183 clusters.push_back(sp->clusterList().first);
184 }
185 }
186
187 // I will follow the following steps to fit the track:
188 // 1. get initial track parameters based on these space points
189 // 2. fit the track segments to get a better estimate of the track
190 // parameters, twice. (first with local parameters, then with perigee
191 // parameters)
192 // 3. create the detector element road based on the track parameters.
193 // 4. forward extension of the track with smoothing
194 // 5. backward smoother of the track
195 // 6. create a Trk::Track object and store it in the outputTracks
196 // collection. If step 3 - 6 failed, I will refit the track from step 2 with
197 // overlap removal and store it in the outputTracks collection.
198
199 // other options we could explore. See SiTrajectory_xk.h for more details.
200 // backwardExtension, forwardFilter, filterWithPreciseClustersError,
201
202 // conformal mapping for track parameters
203 auto trkParameters = m_seedFitter->fit(trackCandidate);
204 if (trkParameters == nullptr) {
205 ATH_MSG_WARNING("Conformal mapping failed");
206 continue;
207 }
208
209 // step 2. fit the pixel-based track with the track fitter
211 // first fit the track with local parameters and without outlier removal.
212 bool outlier_removal = false;
213 std::unique_ptr<Trk::Track> track = m_trackFitter->fit(
214 ctx, clusters, *trkParameters, outlier_removal, matEffects);
215 if (track != nullptr && track->perigeeParameters() != nullptr) {
216 // fit the track again with perigee parameters and without outlier
217 // removal.
218 track = m_trackFitter->fit(ctx, clusters, *track->perigeeParameters(),
219 outlier_removal, matEffects);
220 }
221 // done with step 2.
222
223 if (track == nullptr)
224 continue;
225 const Trk::TrackParameters& Tp = *(track->perigeeParameters());
226 bool is_extension_successful = false;
227
228 // step 3. building the road
229 SiDetElementRoadMakerData_xk roadMakerData;
230 std::vector<const InDetDD::SiDetectorElement*> trackRoad;
231 m_roadmaker->detElementsRoad(ctx, fieldCache, Tp, Trk::alongMomentum,
232 trackRoad, roadMakerData);
233 if (!trackRoad.empty()) {
234 std::vector<const InDet::SiDetElementBoundaryLink_xk*> DEL;
235 detectorElementLinks(trackRoad, DEL, ctx);
236
237 data.tools().setBremNoise(false, false);
238 data.tracks().erase(data.tracks().begin(), data.tracks().end());
239 data.statistic().fill(false);
240 ++data.inputseeds();
241
242 // step 3.5 initialize the trajectory
243 std::vector<const InDet::SiCluster*> Cl;
244 spacePointsToClusters(trackCandidate, Cl);
245 bool Qr;
246 bool Q = data.trajectory().initialize(true, true, pixelClusters.cptr(),
247 stripClusters.cptr(), Tp, Cl, DEL,
248 Qr, ctx);
249
250 if (Q) {
251 // step 4. forward extension of the track
252 int itmax = 10;
253 bool do_smooth = true;
254 if (data.trajectory().forwardExtension(do_smooth, itmax, ctx)) {
255 // step 5. backward smoother of the track
256 if (data.trajectory().backwardSmoother(false, ctx)) {
258 data.trajectory().sortStep();
259
260 Trk::TrackInfo info;
261 info.setPatternRecognitionInfo(
263 info.setParticleHypothesis(Trk::pion);
264
265 Trk::Track final_track(
266 info,
267 std::make_unique<Trk::TrackStates>(
268 data.trajectory().convertToSimpleTrackStateOnSurface(ctx)),
269 data.trajectory().convertToFitQuality());
270 // refit the track with overlap removal.
271 auto extended_track =
272 m_trackFitter->fit(ctx, final_track, true, matEffects);
273 if (extended_track != nullptr &&
274 extended_track->trackSummary() != nullptr) {
275 num_extended_tracks++;
276 is_extension_successful = true;
277 outputTracks->push_back(extended_track.release());
278 }
279 }
280 } // end of forward extension. We could try backward smoother if
281 // forward extension failed.
282 }
283 }
284 if (!is_extension_successful) {
285 track = m_trackFitter->fit(ctx, clusters, *track->perigeeParameters(),
286 true, matEffects);
287 if (track != nullptr && track->trackSummary() != nullptr) {
288 outputTracks->push_back(track.release());
289 }
290 }
291 }
292
293 data.tracks().erase(data.tracks().begin(), data.tracks().end());
294 ATH_MSG_DEBUG("Run " << runNumber << ", Event " << eventNumber << " has "
295 << outputTracks->size() << " tracks stored, with "
296 << num_extended_tracks << " extended.");
297 return StatusCode::SUCCESS;
298}
299
301// Convert space points to clusters and (for Run 4) detector elements
303
305 const std::vector<const Trk::SpacePoint*>& Sp,
306 std::vector<const InDet::SiCluster*>& Sc,
307 std::optional<
308 std::reference_wrapper<std::vector<const InDetDD::SiDetectorElement*>>>
309 DE) {
310 Sc.reserve(Sp.size());
312 for (const Trk::SpacePoint* s : Sp) {
314 const Trk::PrepRawData* p = s->clusterList().first;
315 if (p) {
317 const InDet::SiCluster* c = static_cast<const InDet::SiCluster*>(p);
318 if (c) {
319 Sc.push_back(c);
320 }
321 }
323 p = s->clusterList().second;
324 if (p) {
325 const InDet::SiCluster* c = static_cast<const InDet::SiCluster*>(p);
326 if (c) {
327 Sc.push_back(c);
328 }
329 }
330 }
331
333 std::vector<const InDet::SiCluster*>::iterator cluster = Sc.begin(),
334 nextCluster,
335 endClusters = Sc.end();
336
339 if (DE) {
340 DE->get().reserve(Sc.size());
341 }
342 for (; cluster != endClusters; ++cluster) {
343
344 const InDetDD::SiDetectorElement* de = (*cluster)->detectorElement();
345
346 nextCluster = cluster;
347 ++nextCluster;
348 for (; nextCluster != endClusters; ++nextCluster) {
349 if (de == (*nextCluster)->detectorElement()) {
350 return false;
351 }
352 }
353 if (DE) {
354 DE->get().push_back(de);
355 }
356 }
357 return true;
358}
359
361// Convert detector elements to detector element links
363
365 std::vector<const InDetDD::SiDetectorElement*>& DE,
366 std::vector<const InDet::SiDetElementBoundaryLink_xk*>& DEL,
367 const EventContext& ctx) const {
368 const InDet::SiDetElementBoundaryLinks_xk* boundaryPixel{nullptr};
369 const InDet::SiDetElementBoundaryLinks_xk* boundaryStrip{nullptr};
370
372 m_boundaryPixelKey, ctx);
373 boundaryPixel = *boundaryPixelHandle;
374 if (boundaryPixel == nullptr) {
375 ATH_MSG_FATAL(m_boundaryPixelKey.fullKey() << " returns null pointer");
376 }
377
379 m_boundaryStripKey, ctx);
380 boundaryStrip = *boundaryStripHandle;
381 if (boundaryStrip == nullptr) {
382 ATH_MSG_FATAL(m_boundaryStripKey.fullKey() << " returns null pointer");
383 }
384
385 DEL.reserve(DE.size());
386 for (const InDetDD::SiDetectorElement* d : DE) {
387 IdentifierHash id = d->identifyHash();
388 if (d->isPixel() && boundaryPixel && id < boundaryPixel->size())
389 DEL.push_back(&(*boundaryPixel)[id]);
390 else if (d->isSCT() && boundaryStrip && id < boundaryStrip->size())
391 DEL.push_back(&(*boundaryStrip)[id]);
392 }
393}
394
396 const EventContext& ctx, SiCombinatorialTrackFinderData_xk& data) const {
397
402 ctx};
403 const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
404 if (fieldCondObj == nullptr) {
405 std::string msg =
406 "InDet::SiCombinatorialTrackFinder_xk::initializeCombinatorialData: "
407 "Failed to retrieve AtlasFieldCacheCondObj with key " +
409 throw(std::runtime_error(msg));
410 }
411 data.setFieldCondObj(fieldCondObj);
412
415 data.setTools(&*m_proptool, &*m_updatortool, &*m_riocreator,
418 : nullptr,
421 : nullptr,
423 if (!m_pixelDetElStatus.empty()) {
425 m_pixelDetElStatus, ctx);
426 data.setPixelDetectorElementStatus(pixelDetElStatus.cptr());
427 }
428 if (!m_stripDetElStatus.empty()) {
430 m_stripDetElStatus, ctx);
431 data.setSCTDetectorElementStatus(stripDetElStatus.cptr());
432 }
433
434 // Set the ITk Geometry setup
435 data.setITkGeometry(true);
436 // Set the ITk Fast Tracking setup
437 data.setFastTracking(false);
438}
439
442
443 data.setCosmicTrack(0);
444 data.setNclusmin(m_nclusmin);
445 data.setNclusminb(std::max(3, data.nclusmin() - 1));
446 data.setNwclusmin(m_nwclusmin);
447 data.setNholesmax(m_nholesmax);
448 data.setDholesmax(m_dholesmax);
449
450 data.tools().setHolesClusters(data.nholesmax(), data.dholesmax(),
451 data.nclusmin());
452
453 data.tools().setAssociation(0);
454 data.setSimpleTrack(false);
455
456 data.setPTmin(m_pTmin);
457 data.setPTminBrem(m_pTminBrem);
458 data.setXi2max(m_xi2max);
459 data.setXi2maxNoAdd(m_xi2maxNoAdd);
460 data.setXi2maxlink(m_xi2maxlink);
461 data.tools().setXi2pTmin(data.xi2max(), data.xi2maxNoAdd(), data.xi2maxlink(),
462 data.pTmin());
463 data.tools().setMultiTracks(m_doMultiTracksProd, m_xi2multitracks);
464
465 data.trajectory().setParameters();
466}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
static Double_t sp
static Double_t Tp(Double_t *t, Double_t *par)
#define VALIDATE_STATUS_ARRAY_ACTIVATED
size_t size() const
Number of registered mappings.
An algorithm that can be simultaneously executed in multiple threads.
void getInitializedCache(MagField::AtlasFieldCache &cache) const
get B field cache for evaluation as a function of 2-d or 3-d position.
This is a "hash" representation of an Identifier.
Class to hold geometrical description of a silicon detector element.
void initializeCombinatorialData(const EventContext &ctx, SiCombinatorialTrackFinderData_xk &data) const
ToolHandle< Trk::IBoundaryCheckTool > m_boundaryCheckTool
ToolHandle< IGNNTrackReaderTool > m_gnnTrackReader
virtual StatusCode execute(const EventContext &ctx) const override
ToolHandle< IGNNTrackFinder > m_gnnTrackFinder
SG::ReadCondHandleKey< InDet::SiDetElementBoundaryLinks_xk > m_boundaryPixelKey
ToolHandle< InDet::ISiDetElementsRoadMaker > m_roadmaker
SG::ReadHandleKey< InDet::SiDetectorElementStatus > m_stripDetElStatus
Optional read handle to get status data to test whether a Strip detector element is good.
PublicToolHandle< Trk::IPatternParametersPropagator > m_proptool
SG::ReadHandleKey< InDet::SCT_ClusterContainer > m_stripClusterKey
PublicToolHandle< Trk::IRIO_OnTrackCreator > m_riocreator
void getTrackQualityCuts(SiCombinatorialTrackFinderData_xk &data) const
void detectorElementLinks(std::vector< const InDetDD::SiDetectorElement * > &DE, std::vector< const InDet::SiDetElementBoundaryLink_xk * > &DEL, const EventContext &ctx) const
ToolHandle< ISeedFitter > m_seedFitter
GNN-based track finding tool that produces track candidates.
SG::ReadCondHandleKey< InDet::SiDetElementBoundaryLinks_xk > m_boundaryStripKey
ToolHandle< Trk::ITrackFitter > m_trackFitter
Track Fitter.
SG::ReadHandleKey< InDet::PixelClusterContainer > m_pixelClusterKey
static bool spacePointsToClusters(const std::vector< const Trk::SpacePoint * > &, std::vector< const InDet::SiCluster * > &, std::optional< std::reference_wrapper< std::vector< const InDetDD::SiDetectorElement * > > >=std::nullopt)
SG::ReadCondHandleKey< AtlasFieldCacheCondObj > m_fieldCondObjInputKey
Trk::MagneticFieldProperties m_fieldprop
Magnetic field properties.
ToolHandle< IInDetConditionsTool > m_stripCondSummaryTool
PublicToolHandle< Trk::IPatternParametersUpdator > m_updatortool
SG::ReadHandleKey< SpacePointContainer > m_SpacePointsStripKey
GNNSeedingTrackMaker(const std::string &name, ISvcLocator *pSvcLocator)
SG::ReadHandleKey< SpacePointContainer > m_SpacePointsPixelKey
virtual StatusCode initialize() override
SG::ReadHandleKey< InDet::SiDetectorElementStatus > m_pixelDetElStatus
Optional read handle to get status data to test whether a pixel detector element is good.
SG::WriteHandleKey< TrackCollection > m_outputTracksKey
ToolHandle< IInDetConditionsTool > m_pixelCondSummaryTool
InDet::SiCombinatorialTrackFinderData_xk holds event dependent data used by SiCombinatorialTrackFinde...
InDet::SiDetElementRoadMakerData_xk holds event dependent data used by SiDetElementRoadMaker_xk.
Local cache for magnetic field (based on MagFieldServices/AtlasFieldSvcTLS.h).
Property holding a SG store/key/clid from which a ReadHandle is made.
const_pointer_type cptr()
Dereference the pointer.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
magnetic field properties to steer the behavior of the extrapolation
Contains information about the 'fitter' of this track.
@ SiSPSeededFinder
Tracks from SiSPSeedFinder.
@ SiSPSeededFinderSimple
for tracks processed by the trigger version of the SiSPSeededFinder
@ alongMomentum
@ FastField
call the fast field access method of the FieldSvc
@ NoField
Field is set to 0., 0., 0.,.
@ FullField
Field is set to be realistic, but within a given Volume.
ParticleHypothesis
Enumeration for Particle hypothesis respecting the interaction with material.
ParametersBase< TrackParametersDim, Charged > TrackParameters