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
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.
130 if (not data.isInitialized())
132 // Erase statistic information
133 //
134 data.inputseeds() = 0;
135 data.goodseeds() = 0;
136 data.inittracks() = 0;
137 data.findtracks() = 0;
138 data.roadbug() = 0;
139 // Set track info
140 //
141 data.trackinfo().setPatternRecognitionInfo(Trk::TrackInfo::SiSPSeededFinder);
142 data.setCosmicTrack(0);
143 data.setPixContainer(pixelClusters.cptr());
144 data.setSctContainer(stripClusters.cptr());
145
147
148 // Get AtlasFieldCache
149 MagField::AtlasFieldCache fieldCache;
150
153 ctx};
154 const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
155 if (fieldCondObj == nullptr) {
157 "InDet::SiTrackMaker_xk::getTracks: Failed to retrieve "
158 "AtlasFieldCacheCondObj with key "
159 << m_fieldCondObjInputKey.key());
160 return StatusCode::FAILURE;
161 }
162 fieldCondObj->getInitializedCache(fieldCache);
163
164 int num_extended_tracks = 0;
165
166 for (auto& trackIndices : gnnTrackCandidates) {
167
168 std::vector<const Trk::PrepRawData*> clusters; // only pixel clusters!
169 std::vector<const Trk::SpacePoint*> trackCandidate;
170 trackCandidate.reserve(trackIndices.size());
171
172 for (auto& id : trackIndices) {
174 if (id > spacePoints.size()) {
175 ATH_MSG_WARNING("SpacePoint index out of range");
176 continue;
177 }
178 const Trk::SpacePoint* sp = spacePoints[id];
179 if (sp != nullptr) {
180 trackCandidate.push_back(sp);
181 clusters.push_back(sp->clusterList().first);
182 }
183 }
184
185 // I will follow the following steps to fit the track:
186 // 1. get initial track parameters based on these space points
187 // 2. fit the track segments to get a better estimate of the track
188 // parameters, twice. (first with local parameters, then with perigee
189 // parameters)
190 // 3. create the detector element road based on the track parameters.
191 // 4. forward extension of the track with smoothing
192 // 5. backward smoother of the track
193 // 6. create a Trk::Track object and store it in the outputTracks
194 // collection. If step 3 - 6 failed, I will refit the track from step 2 with
195 // overlap removal and store it in the outputTracks collection.
196
197 // other options we could explore. See SiTrajectory_xk.h for more details.
198 // backwardExtension, forwardFilter, filterWithPreciseClustersError,
199
200 // conformal mapping for track parameters
201 auto trkParameters = m_seedFitter->fit(trackCandidate);
202 if (trkParameters == nullptr) {
203 ATH_MSG_WARNING("Conformal mapping failed");
204 continue;
205 }
206
207 // step 2. fit the pixel-based track with the track fitter
209 // first fit the track with local parameters and without outlier removal.
210 bool outlier_removal = false;
211 std::unique_ptr<Trk::Track> track = m_trackFitter->fit(
212 ctx, clusters, *trkParameters, outlier_removal, matEffects);
213 if (track != nullptr && track->perigeeParameters() != nullptr) {
214 // fit the track again with perigee parameters and without outlier
215 // removal.
216 track = m_trackFitter->fit(ctx, clusters, *track->perigeeParameters(),
217 outlier_removal, matEffects);
218 }
219 // done with step 2.
220
221 if (track == nullptr)
222 continue;
223 const Trk::TrackParameters& Tp = *(track->perigeeParameters());
224 bool is_extension_successful = false;
225
226 // step 3. building the road
227 SiDetElementRoadMakerData_xk roadMakerData;
228 std::vector<const InDetDD::SiDetectorElement*> trackRoad;
229 m_roadmaker->detElementsRoad(ctx, fieldCache, Tp, Trk::alongMomentum,
230 trackRoad, roadMakerData);
231 if (!trackRoad.empty()) {
232 std::vector<const InDet::SiDetElementBoundaryLink_xk*> DEL;
233 detectorElementLinks(trackRoad, DEL, ctx);
234
235 data.tools().setBremNoise(false, false);
236 data.tracks().erase(data.tracks().begin(), data.tracks().end());
237 data.statistic().fill(false);
238 ++data.inputseeds();
239
240 // step 3.5 initialize the trajectory
241 std::vector<const InDet::SiCluster*> Cl;
242 spacePointsToClusters(trackCandidate, Cl);
243 bool Qr;
244 bool Q = data.trajectory().initialize(true, true, pixelClusters.cptr(),
245 stripClusters.cptr(), Tp, Cl, DEL,
246 Qr, ctx);
247
248 if (Q) {
249 // step 4. forward extension of the track
250 int itmax = 10;
251 bool do_smooth = true;
252 if (data.trajectory().forwardExtension(do_smooth, itmax, ctx)) {
253 // step 5. backward smoother of the track
254 if (data.trajectory().backwardSmoother(false, ctx)) {
256 data.trajectory().sortStep();
257
258 Trk::TrackInfo info;
259 info.setPatternRecognitionInfo(
261 info.setParticleHypothesis(Trk::pion);
262
263 Trk::Track final_track(
264 info,
265 std::make_unique<Trk::TrackStates>(
266 data.trajectory().convertToSimpleTrackStateOnSurface(ctx)),
267 data.trajectory().convertToFitQuality());
268 // refit the track with overlap removal.
269 auto extended_track =
270 m_trackFitter->fit(ctx, final_track, true, matEffects);
271 if (extended_track != nullptr &&
272 extended_track->trackSummary() != nullptr) {
273 num_extended_tracks++;
274 is_extension_successful = true;
275 outputTracks->push_back(extended_track.release());
276 }
277 }
278 } // end of forward extension. We could try backward smoother if
279 // forward extension failed.
280 }
281 }
282 if (!is_extension_successful) {
283 track = m_trackFitter->fit(ctx, clusters, *track->perigeeParameters(),
284 true, matEffects);
285 if (track != nullptr && track->trackSummary() != nullptr) {
286 outputTracks->push_back(track.release());
287 }
288 }
289 }
290
291 data.tracks().erase(data.tracks().begin(), data.tracks().end());
292 ATH_MSG_DEBUG("Run " << runNumber << ", Event " << eventNumber << " has "
293 << outputTracks->size() << " tracks stored, with "
294 << num_extended_tracks << " extended.");
295 return StatusCode::SUCCESS;
296}
297
299// Convert space points to clusters and (for Run 4) detector elements
301
303 const std::vector<const Trk::SpacePoint*>& Sp,
304 std::vector<const InDet::SiCluster*>& Sc,
305 std::optional<
306 std::reference_wrapper<std::vector<const InDetDD::SiDetectorElement*>>>
307 DE) {
308 Sc.reserve(Sp.size());
310 for (const Trk::SpacePoint* s : Sp) {
312 const Trk::PrepRawData* p = s->clusterList().first;
313 if (p) {
315 const InDet::SiCluster* c = static_cast<const InDet::SiCluster*>(p);
316 if (c) {
317 Sc.push_back(c);
318 }
319 }
321 p = s->clusterList().second;
322 if (p) {
323 const InDet::SiCluster* c = static_cast<const InDet::SiCluster*>(p);
324 if (c) {
325 Sc.push_back(c);
326 }
327 }
328 }
329
331 std::vector<const InDet::SiCluster*>::iterator cluster = Sc.begin(),
332 nextCluster,
333 endClusters = Sc.end();
334
337 if (DE) {
338 DE->get().reserve(Sc.size());
339 }
340 for (; cluster != endClusters; ++cluster) {
341
342 const InDetDD::SiDetectorElement* de = (*cluster)->detectorElement();
343
344 nextCluster = cluster;
345 ++nextCluster;
346 for (; nextCluster != endClusters; ++nextCluster) {
347 if (de == (*nextCluster)->detectorElement()) {
348 return false;
349 }
350 }
351 if (DE) {
352 DE->get().push_back(de);
353 }
354 }
355 return true;
356}
357
359// Convert detector elements to detector element links
361
363 std::vector<const InDetDD::SiDetectorElement*>& DE,
364 std::vector<const InDet::SiDetElementBoundaryLink_xk*>& DEL,
365 const EventContext& ctx) const {
366 const InDet::SiDetElementBoundaryLinks_xk* boundaryPixel{nullptr};
367 const InDet::SiDetElementBoundaryLinks_xk* boundaryStrip{nullptr};
368
370 m_boundaryPixelKey, ctx);
371 boundaryPixel = *boundaryPixelHandle;
372 if (boundaryPixel == nullptr) {
373 ATH_MSG_FATAL(m_boundaryPixelKey.fullKey() << " returns null pointer");
374 }
375
377 m_boundaryStripKey, ctx);
378 boundaryStrip = *boundaryStripHandle;
379 if (boundaryStrip == nullptr) {
380 ATH_MSG_FATAL(m_boundaryStripKey.fullKey() << " returns null pointer");
381 }
382
383 DEL.reserve(DE.size());
384 for (const InDetDD::SiDetectorElement* d : DE) {
385 IdentifierHash id = d->identifyHash();
386 if (d->isPixel() && boundaryPixel && id < boundaryPixel->size())
387 DEL.push_back(&(*boundaryPixel)[id]);
388 else if (d->isSCT() && boundaryStrip && id < boundaryStrip->size())
389 DEL.push_back(&(*boundaryStrip)[id]);
390 }
391}
392
394 const EventContext& ctx, SiCombinatorialTrackFinderData_xk& data) const {
395
400 ctx};
401 const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
402 if (fieldCondObj == nullptr) {
403 std::string msg =
404 "InDet::SiCombinatorialTrackFinder_xk::initializeCombinatorialData: "
405 "Failed to retrieve AtlasFieldCacheCondObj with key " +
407 throw(std::runtime_error(msg));
408 }
409 data.setFieldCondObj(fieldCondObj);
410
413 data.setTools(&*m_proptool, &*m_updatortool, &*m_riocreator,
416 : nullptr,
419 : nullptr,
421 if (!m_pixelDetElStatus.empty()) {
423 m_pixelDetElStatus, ctx);
424 data.setPixelDetectorElementStatus(pixelDetElStatus.cptr());
425 }
426 if (!m_stripDetElStatus.empty()) {
428 m_stripDetElStatus, ctx);
429 data.setSCTDetectorElementStatus(stripDetElStatus.cptr());
430 }
431
432 // Set the ITk Geometry setup
433 data.setITkGeometry(true);
434 // Set the ITk Fast Tracking setup
435 data.setFastTracking(false);
436}
437
440
441 data.setCosmicTrack(0);
442 data.setNclusmin(m_nclusmin);
443 data.setNclusminb(std::max(3, data.nclusmin() - 1));
444 data.setNwclusmin(m_nwclusmin);
445 data.setNholesmax(m_nholesmax);
446 data.setDholesmax(m_dholesmax);
447
448 data.tools().setHolesClusters(data.nholesmax(), data.dholesmax(),
449 data.nclusmin());
450
451 data.tools().setAssociation(0);
452 data.setSimpleTrack(false);
453
454 data.setPTmin(m_pTmin);
455 data.setPTminBrem(m_pTminBrem);
456 data.setXi2max(m_xi2max);
457 data.setXi2maxNoAdd(m_xi2maxNoAdd);
458 data.setXi2maxlink(m_xi2maxlink);
459 data.tools().setXi2pTmin(data.xi2max(), data.xi2maxNoAdd(), data.xi2maxlink(),
460 data.pTmin());
461 data.tools().setMultiTracks(m_doMultiTracksProd, m_xi2multitracks);
462
463 data.trajectory().setParameters();
464}
#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)
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
static Double_t sp
static Double_t Tp(Double_t *t, Double_t *par)
#define VALIDATE_STATUS_ARRAY_ACTIVATED
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