ATLAS Offline Software
MooTrackBuilder.cxx
Go to the documentation of this file.
1 
2 /*
3  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
4 */
5 
6 #include "MooTrackBuilder.h"
7 
8 #include <set>
9 
10 #include "AthenaKernel/Timeout.h"
26 
27 namespace Muon {
28  static const MooTrackBuilder::PrepVec emptyPhiHits{};
29 
30  MooTrackBuilder::MooTrackBuilder(const std::string& t, const std::string& n, const IInterface* p) : AthAlgTool(t, n, p) {
31  declareInterface<IMuonSegmentTrackBuilder>(this);
32  declareInterface<MooTrackBuilder>(this);
33  declareInterface<IMuonTrackRefiner>(this);
34  declareInterface<IMuonTrackBuilder>(this);
35  }
36 
38  ATH_CHECK(m_fitter.retrieve());
39  ATH_CHECK(m_slFitter.retrieve());
41  ATH_CHECK(m_errorOptimisationTool.retrieve(DisableTool{m_errorOptimisationTool.empty()}));
42  ATH_CHECK(m_candidateHandler.retrieve());
46  ATH_CHECK(m_idHelperSvc.retrieve());
47  ATH_CHECK(m_edmHelperSvc.retrieve());
48  ATH_CHECK(m_printer.retrieve());
49  ATH_CHECK(m_trackToSegmentTool.retrieve());
50  ATH_CHECK(m_seededSegmentFinder.retrieve());
51  ATH_CHECK(m_mdtRotCreator.retrieve());
52  ATH_CHECK(m_compRotCreator.retrieve());
53  ATH_CHECK(m_propagator.retrieve());
54  ATH_CHECK(m_pullCalculator.retrieve());
55  ATH_CHECK(m_trackSummaryTool.retrieve());
56 
57  return StatusCode::SUCCESS;
58  }
59 
61  if (m_nTimedOut > 0 && m_ncalls > 0) {
62  double scale = 1. / m_ncalls;
63  ATH_MSG_INFO(" Number of calls that timed out " << m_nTimedOut << " fraction of total calls " << scale * m_nTimedOut);
64  }
65  return StatusCode::SUCCESS;
66  }
67 
68  std::unique_ptr<Trk::Track> MooTrackBuilder::refit(const EventContext& ctx, Trk::Track& track) const {
69  // use slFitter for straight line fit, or toroid off, otherwise use normal Fitter
70 
71  if (m_edmHelperSvc->isSLTrack(track)) return m_slFitter->refit(ctx, track);
72 
73  // Also check if toriod is off:
74  MagField::AtlasFieldCache fieldCache;
75  // Get field cache object
77  const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
78 
79  if (!fieldCondObj) {
80  ATH_MSG_ERROR("refit: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCacheCondObjInputKey.key());
81  return nullptr;
82  }
83  fieldCondObj->getInitializedCache(fieldCache);
84  if (!fieldCache.toroidOn()) return m_slFitter->refit(ctx, track);
85 
86  // if not refit tool specified do a pure refit
87  if (m_errorOptimisationTool.empty()) return m_fitter->refit(ctx, track);
88  std::unique_ptr<Trk::Track> optTrack = m_errorOptimisationTool->optimiseErrors(track, ctx);
89  return optTrack;
90  }
91 
92  void MooTrackBuilder::refine(const EventContext& ctx, MuPatTrack& track) const {
93 
94  ATH_MSG_VERBOSE("refine: before recovery " << std::endl
95  << m_printer->print(track.track()) << std::endl
96  << m_printer->print(track.track().measurementsOnTrack()->stdcont()));
97 
98  std::unique_ptr<Trk::Track> finalTrack(m_muonChamberHoleRecoverTool->recover(track.track(), ctx));
99  if (!finalTrack) { ATH_MSG_WARNING(" final track lost, this should not happen "); }
100  ATH_MSG_VERBOSE("refine: after recovery " << std::endl
101  << m_printer->print(*finalTrack) << std::endl
102  << m_printer->print(finalTrack->measurementsOnTrack()->stdcont()));
103 
104  // generate a track summary for this track
105  if (m_trackSummaryTool.isEnabled()) { m_trackSummaryTool->computeAndReplaceTrackSummary(*finalTrack, false); }
106 
107  bool recalibrateMDTHits = m_recalibrateMDTHits;
108  bool recreateCompetingROTs = true;
109  std::unique_ptr<Trk::Track> recalibratedTrack = recalibrateHitsOnTrack(ctx, *finalTrack, recalibrateMDTHits, recreateCompetingROTs);
110  if (!recalibratedTrack) {
111  ATH_MSG_WARNING(" failed to recalibrate hits on track " << std::endl << m_printer->print(*finalTrack));
112  } else
113  finalTrack.swap(recalibratedTrack);
114 
115  std::unique_ptr<Trk::Track> refittedTrack = refit(ctx, *finalTrack);
116  if (!refittedTrack) {
117  ATH_MSG_VERBOSE(" failed to refit track " << std::endl
118  << m_printer->print(*finalTrack) << std::endl
119  << m_printer->printStations(*finalTrack));
120  } else
121  finalTrack.swap(refittedTrack);
122 
123  // redo holes as they are dropped in the fitter
124  std::unique_ptr<Trk::Track> finalTrackWithHoles(m_muonChamberHoleRecoverTool->recover(*finalTrack, ctx));
125  if (!finalTrackWithHoles) {
126  ATH_MSG_WARNING(" failed to add holes to final track, this should not happen ");
127  } else
128  finalTrack.swap(finalTrackWithHoles);
129 
130  std::unique_ptr<Trk::Track> entryRecordTrack(m_trackExtrapolationTool->extrapolate(*finalTrack, ctx));
131  if (entryRecordTrack) {
132  finalTrack.swap(entryRecordTrack);
133  ATH_MSG_VERBOSE(" track at muon entry record " << std::endl << m_printer->print(*finalTrack));
134  }
135  m_candidateHandler->updateTrack(track, finalTrack);
136  }
137 
138  std::unique_ptr<MuonSegment> MooTrackBuilder::combineToSegment(const EventContext& ctx, const MuonSegment& seg1, const MuonSegment& seg2, const PrepVec& externalPhiHits) const {
139  // try to get track
140  std::unique_ptr<Trk::Track> track = combine(ctx, seg1, seg2, externalPhiHits);
141 
142  if (!track) return nullptr;
143 
144  // create MuonSegment
145  std::unique_ptr<MuonSegment> seg{m_trackToSegmentTool->convert(ctx, *track)};
146  if (!seg) { ATH_MSG_WARNING(" conversion of track failed!! "); }
147 
148  return seg;
149  }
150 
151  std::unique_ptr<Trk::Track> MooTrackBuilder::combine(const EventContext& ctx, const MuonSegment& seg1, const MuonSegment& seg2,
152  const PrepVec& externalPhiHits) const {
153 
154  // convert segments
155  std::unique_ptr<MuPatSegment> segInfo1{m_candidateHandler->createSegInfo(ctx, seg1)};
156  if (!segInfo1) {return nullptr; }
157  std::unique_ptr<MuPatSegment> segInfo2{m_candidateHandler->createSegInfo(ctx, seg2)};
158  if (!segInfo2) { return nullptr; }
159 
160  // call fit()
161  return combine(ctx, *segInfo1, *segInfo2, externalPhiHits);
162  }
163 
164  std::unique_ptr<MuonSegment> MooTrackBuilder::combineToSegment(const EventContext& ctx, const MuPatCandidateBase& firstCandidate, const MuPatCandidateBase& secondCandidate,
165  const PrepVec& externalPhiHits) const {
166  // try to get track
167  std::unique_ptr<Trk::Track> track = combine(ctx, firstCandidate, secondCandidate, externalPhiHits);
168 
169  if (!track) return nullptr;
170 
171  // create MuonSegment
172  std::unique_ptr<MuonSegment> seg{m_trackToSegmentTool->convert(ctx, *track)};
173  if (!seg) { ATH_MSG_WARNING(" conversion of track failed!! "); }
174 
175  return seg;
176  }
177 
178  std::unique_ptr<Trk::Track> MooTrackBuilder::combine(const EventContext& ctx, const MuPatCandidateBase& firstCandidate,
179  const MuPatCandidateBase& secondCandidate, const PrepVec& externalPhiHits) const {
180  ++m_ncalls;
181 
182  if (m_doTimeOutChecks && Athena::Timeout::instance(ctx).reached()) {
183  ATH_MSG_DEBUG("Timeout reached. Aborting sequence.");
184  ++m_nTimedOut;
185  return nullptr;
186  }
187 
188  std::set<MuonStationIndex::StIndex> stations = firstCandidate.stations();
189  stations.insert(secondCandidate.stations().begin(), secondCandidate.stations().end());
190  unsigned int nstations = stations.size();
191 
192  MagField::AtlasFieldCache fieldCache;
193  // Get field cache object
195  const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
196 
197  if (!fieldCondObj) {
198  ATH_MSG_ERROR("combine: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCacheCondObjInputKey.key());
199  return nullptr;
200  }
201  fieldCondObj->getInitializedCache(fieldCache);
202  using namespace MuonStationIndex;
203  bool slFit = !fieldCache.toroidOn() || nstations == 1 ||
204  (nstations == 2 && (stations.count(StIndex::EM) &&
205  (stations.count(StIndex::BO) || stations.count(StIndex::EO))));
206  if (msgLvl(MSG::DEBUG)) {
207  msg(MSG::DEBUG) << MSG::DEBUG << " combining entries: nstations " << nstations << " types:";
208  for (std::set<StIndex>::const_iterator it = stations.begin(); it != stations.end(); ++it) {
209  msg(MSG::DEBUG) << MSG::DEBUG << " " << stName(*it);
210  }
211  if (slFit) {
212  msg(MSG::DEBUG) << " doing SL fit ";
213  } else {
214  msg(MSG::DEBUG) << " doing curved fit ";
215  }
216  msg(MSG::DEBUG) << endmsg;
217  }
218 
219  const MuPatTrack* trkCan1 = dynamic_cast<const MuPatTrack*>(&firstCandidate);
220  const MuPatTrack* trkCan2 = dynamic_cast<const MuPatTrack*>(&secondCandidate);
221 
222  const MuPatSegment* segCan1 = dynamic_cast<const MuPatSegment*>(&firstCandidate);
223  const MuPatSegment* segCan2 = dynamic_cast<const MuPatSegment*>(&secondCandidate);
224 
225  const MuPatTrack* candidate = nullptr;
226  const MuPatSegment* segment = nullptr;
227  if (trkCan1 && segCan2) {
228  candidate = trkCan1;
229  segment = segCan2;
230  } else if (trkCan2 && segCan1) {
231  candidate = trkCan2;
232  segment = segCan1;
233  }
234 
235  // check whether this combination was already tried, if yes reject the combination
236  if (candidate && segment) {
237  ATH_MSG_DEBUG(" Track/segment combination");
238  const std::vector<MuPatSegment*>& excl = candidate->excludedSegments();
239  if (std::find(excl.begin(),excl.end(), segment) != excl.end()){
240  ATH_MSG_DEBUG(" Rejected segment based on exclusion list");
241  return nullptr;
242  }
243  }
244 
245  // the following bit of code checks whether the current combination of segments was already tested
246  if (m_useTrackingHistory) {
247  // create a set of all segments of the would-be candidate
248  std::set<const MuPatSegment*> segments;
249  if ((segCan1 && segCan2)) {
250  segments.insert(segCan1);
251  segments.insert(segCan2);
252  }
253  if (candidate && segment) {
254  segments.insert(segment);
255  segments.insert(candidate->segments().begin(), candidate->segments().end());
256  }
257  // now loop over the segments and check if any of them is associated with a track that contains all of the segments
258 
259  for (const MuPatSegment* used : segments) {
260  // loop over the tracks associated with the current segment
261  for (const MuPatTrack* assoc_track : used->tracks()) {
262  // loop over the segments associated with the track
263  std::set<const MuPatSegment*> foundSegments;
264  for (const MuPatSegment* segOnTrack : assoc_track->segments()) {
265  if (segments.count(segOnTrack)) foundSegments.insert(segOnTrack);
266  }
267  // if all segments are already part of an existing track, don't perform the fit
268  if (foundSegments.size() == segments.size()) {
269  ATH_MSG_DEBUG("Combination already part of an existing track");
270  return nullptr;
271  }
272 
273  // if all segments but one are already part of an existing track, check the exclusion list
274  if (candidate && !candidate->excludedSegments().empty() && foundSegments.size() == segments.size() - 1) {
275  // create destination vector for segments that are not found
276  std::vector<const MuPatSegment*> unassociatedSegments(segments.size(), nullptr);
277  std::vector<const MuPatSegment*>::iterator it = std::set_difference(
278  segments.begin(), segments.end(), foundSegments.begin(), foundSegments.end(), unassociatedSegments.begin());
279  const MuPatSegment* zero = nullptr;
280  unassociatedSegments.erase(std::find(unassociatedSegments.begin(), unassociatedSegments.end(), zero),
281  unassociatedSegments.end());
282 
283  // check whether any pointers found
284  if (it != unassociatedSegments.begin()) {
285  // this should always be one as we required the difference to be one!
286  if (unassociatedSegments.size() != 1) {
287  ATH_MSG_DEBUG("Inconsistent result from set difference: size result "
288  << unassociatedSegments.size() << " candidate " << segments.size() << " found "
289  << foundSegments.size());
290  return nullptr;
291  }
292 
293  // check that the result is indeed part of the original set
294  if (!segments.count(unassociatedSegments.front())) {
295  ATH_MSG_DEBUG("Segment point not part of the original set, aborting!");
296  return nullptr;
297  }
298 
299  // now check whether the segment is part of the excluded segments
300  std::vector<MuPatSegment*>::const_iterator pos = std::find(
301  candidate->excludedSegments().begin(), candidate->excludedSegments().end(), unassociatedSegments.front());
302  if (pos != candidate->excludedSegments().end()) {
303  ATH_MSG_DEBUG("Segment found in exclusion list, not performing fit");
304  return nullptr;
305  }
306  }
307  }
308  }
309  }
310  }
311 
312  // use slFitter for straight line fit, or toroid off, otherwise use normal Fitter
313  if (slFit) return std::unique_ptr<Trk::Track>(m_slFitter->fit(ctx, firstCandidate, secondCandidate, externalPhiHits));
314 
315  return m_fitter->fit(ctx, firstCandidate, secondCandidate, externalPhiHits);
316  }
317 
318  std::unique_ptr<Trk::Track> MooTrackBuilder::combine(const EventContext& ctx, const Trk::Track& track, const MuonSegment& seg,
319  const PrepVec& externalPhiHits) const {
320 
321  // convert segments
322  std::unique_ptr<Trk::Track> inTrack = std::make_unique<Trk::Track>(track);
323  std::unique_ptr<MuPatTrack> candidate(m_candidateHandler->createCandidate(inTrack));
324  if (!candidate) return nullptr;
325  std::unique_ptr<MuPatSegment> segInfo(m_candidateHandler->createSegInfo(ctx, seg));
326  if (!segInfo) { return nullptr; }
327 
328  // call fit()
329  return combine(ctx, *candidate, *segInfo, externalPhiHits);
330  }
331 
332  std::vector<std::unique_ptr<Trk::Track> > MooTrackBuilder::combineWithSegmentFinding(const EventContext& ctx, const Trk::Track& track, const MuonSegment& seg,
333  const PrepVec& externalPhiHits) const {
334 
335  // convert segments
336  std::unique_ptr<Trk::Track> inTrack = std::make_unique<Trk::Track>(track);
337  std::unique_ptr<MuPatTrack> candidate = m_candidateHandler->createCandidate(inTrack);
338  if (!candidate) return {};
339  std::unique_ptr<MuPatSegment> segInfo(m_candidateHandler->createSegInfo(ctx, seg));
340  if (!segInfo) return {};
341  // call fit()
342  return combineWithSegmentFinding(ctx, *candidate, *segInfo, externalPhiHits);
343  }
344 
345  std::unique_ptr<Trk::TrackParameters> MooTrackBuilder::findClosestParameters(const Trk::Track& track, const Amg::Vector3D& pos) const {
346  // are we in the endcap?
347  bool isEndcap = m_edmHelperSvc->isEndcap(track);
348 
349  // position of segment
350  double posSeg = isEndcap ? pos.z() : pos.perp();
351 
352  // position closest parameters
353  double closest = 1e8;
354  const Trk::TrackParameters* closestParameters = nullptr;
355  bool closestIsMeasured = false;
356 
357  // loop over track and calculate residuals
358  const Trk::TrackStates* states = track.trackStateOnSurfaces();
359  if (!states) {
360  ATH_MSG_DEBUG(" track without states! ");
361  return nullptr;
362  }
363 
364  // loop over TSOSs
366  Trk::TrackStates::const_iterator tsit_end = states->end();
367  for (; tsit != tsit_end; ++tsit) {
368  // check whether state is a measurement
369  const Trk::MeasurementBase* meas = (*tsit)->measurementOnTrack();
370  if (!meas) { continue; }
371 
372  const Trk::TrackParameters* pars = (*tsit)->trackParameters();
373  if (!pars) { continue; }
374 
375  // check whether measured parameters
376  bool isMeasured = pars->covariance();
377 
378  // skip all none measured TrackParameters as soon as we found one with a measurement
379  if (closestIsMeasured && !isMeasured) continue;
380 
381  // calculate position parameters and compare with position segment
382  double posPars = isEndcap ? pars->position().z() : pars->position().perp();
383  double diffPos = std::abs(posPars - posSeg);
384 
385  // accept if measured parameters or the current accepted parameters are not yet measured
386  if ((isMeasured && !closestIsMeasured) || diffPos < closest) {
387  closest = diffPos;
388  closestParameters = pars;
389  closestIsMeasured = isMeasured;
390 
391  // if we are within 100 mm take current
392  if (closest < 100.) { break; }
393  }
394  }
395 
396  // return clone of parameters
397  if (closestParameters) return closestParameters->uniqueClone();
398  return nullptr;
399  }
400 
401  std::unique_ptr<Trk::TrackParameters> MooTrackBuilder::getClosestParameters(const MuPatCandidateBase& candidate, const Trk::Surface& surf) const {
402  // cast to segment, return segment parameters if cast success
403  const MuPatSegment* segCandidate = dynamic_cast<const MuPatSegment*>(&candidate);
404  if (segCandidate) return segCandidate->entryPars().uniqueClone();
405 
406  // for a track candidate, return the closest parameter on the track
407  const MuPatTrack& trkCandidate = dynamic_cast<const MuPatTrack&>(candidate);
408  return getClosestParameters(trkCandidate.track(), surf);
409  }
410 
411  std::unique_ptr<Trk::TrackParameters> MooTrackBuilder::getClosestParameters(const Trk::Track& track, const Trk::Surface& surf) const {
413  }
414 
415  std::vector<std::unique_ptr<Trk::Track> > MooTrackBuilder::combineWithSegmentFinding(const EventContext& ctx, const Trk::Track& track,
416  const Trk::TrackParameters& pars,
417  const std::set<Identifier>& chIds,
418  const PrepVec& patternPhiHits) const {
419  // convert track
420  std::unique_ptr<Trk::Track> inTrack = std::make_unique<Trk::Track>(track);
421  std::unique_ptr<MuPatTrack> can = m_candidateHandler->createCandidate(inTrack);
422  if (!can) { return {}; }
423  return combineWithSegmentFinding(ctx, *can, pars, chIds, patternPhiHits);
424  }
425 
426  std::vector<std::unique_ptr<Trk::Track> > MooTrackBuilder::combineWithSegmentFinding(const EventContext& ctx, const MuPatTrack& candidate,
427  const MuPatSegment& segInfo,
428  const PrepVec& externalPhiHits) const {
435  const MuonSegment& seg = *segInfo.segment;
436  std::vector<std::unique_ptr<Trk::Track> > newTracks;
437 
438  // get chamber Id of segment
439  std::set<Identifier> chIds = m_edmHelperSvc->chamberIds(seg);
440 
441  if (chIds.empty()) return newTracks;
442 
443  // for now do not redo segment making for CSCs
444  if (m_idHelperSvc->isCsc(*chIds.begin())) {
445  if (m_candidateMatchingTool->match(ctx, candidate, segInfo, true)) {
446  std::unique_ptr<Trk::Track> newtrack(m_fitter->fit(ctx, candidate, segInfo, externalPhiHits));
447  if (newtrack) newTracks.push_back(std::move(newtrack));
448  return newTracks;
449  } else {
450  return newTracks;
451  }
452  }
453 
454  const Trk::Track& track = candidate.track();
455  ATH_MSG_DEBUG(" in combineWithSegmentFinding ");
456  ATH_MSG_VERBOSE(" segment " << m_printer->print(seg));
457 
458  // find track parameters on segment surface
459  std::unique_ptr<Trk::TrackParameters> closestPars(findClosestParameters(track, seg.globalPosition()));
460 
461  if (!closestPars) {
462  ATH_MSG_WARNING(" unable to find closest TrackParameters ");
463  return newTracks;
464  }
465 
466  ATH_MSG_VERBOSE(" closest parameter " << m_printer->print(*closestPars));
467 
468  // propagate to segment surface
469  std::unique_ptr<Trk::TrackParameters> exPars(
470  m_propagator->propagate(ctx,*closestPars, seg.associatedSurface(), Trk::anyDirection, false, m_magFieldProperties));
471 
472  if (!exPars) {
473  ATH_MSG_WARNING(" Propagation failed!! ");
474  return newTracks;
475  }
476 
477  ATH_MSG_VERBOSE(" extrapolated parameter " << m_printer->print(*exPars));
478 
479  return combineWithSegmentFinding(ctx, candidate, *exPars, chIds, externalPhiHits);
480  }
481 
482  void MooTrackBuilder::removeDuplicateWithReference(std::unique_ptr<Trk::SegmentCollection>& segments,
483  std::vector<const MuonSegment*>& referenceSegments) const {
484  if (referenceSegments.empty()) return;
485 
486  ATH_MSG_DEBUG(" Removing duplicates from segment vector of size " << segments->size() << " reference size "
487  << referenceSegments.size());
488 
489  CompareMuonSegmentKeys compareSegmentKeys{};
490 
491  // create a vector with pairs of MuonSegmentKey and a pointer to the corresponding segment to resolve ambiguities
492  std::vector<std::pair<MuonSegmentKey, Trk::SegmentCollection::iterator> > segKeys;
493  segKeys.reserve(segments->size());
494 
495  // loop over reference segments and make keys
496  Trk::SegmentCollection::iterator sit = segments->begin();
497  Trk::SegmentCollection::iterator sit_end = segments->end();
498  for (; sit != sit_end; ++sit) {
499  Trk::Segment* tseg = *sit;
500  MuonSegment* mseg = dynamic_cast<MuonSegment*>(tseg);
501  segKeys.emplace_back(MuonSegmentKey(*mseg), sit);
502  }
503 
504  // create a vector with pairs of MuonSegmentKey and a pointer to the corresponding segment to resolve ambiguities
505  std::vector<MuonSegmentKey> referenceSegKeys;
506  referenceSegKeys.reserve(referenceSegments.size());
507 
508  // loop over reference segments and make keys
509  std::vector<const MuonSegment*>::iterator vit = referenceSegments.begin();
510  std::vector<const MuonSegment*>::iterator vit_end = referenceSegments.end();
511  for (; vit != vit_end; ++vit) { referenceSegKeys.emplace_back(**vit); }
512 
513  // loop over segments and compare the current segment with the reference ones
514  std::vector<std::pair<MuonSegmentKey, Trk::SegmentCollection::iterator> >::iterator skit = segKeys.begin();
515  std::vector<std::pair<MuonSegmentKey, Trk::SegmentCollection::iterator> >::iterator skit_end = segKeys.end();
516  for (; skit != skit_end; ++skit) {
517  bool isDuplicate = false;
518 
519  std::vector<MuonSegmentKey>::iterator rskit = referenceSegKeys.begin();
520  std::vector<MuonSegmentKey>::iterator rskit_end = referenceSegKeys.end();
521 
522  for (; rskit != rskit_end; ++rskit) {
523  CompareMuonSegmentKeys::OverlapResult overlapResult = compareSegmentKeys(*rskit, skit->first);
524  if (overlapResult == CompareMuonSegmentKeys::Identical) {
525  ATH_MSG_DEBUG(" discarding identical segment");
526  isDuplicate = true;
527  break;
528  } else if (overlapResult == CompareMuonSegmentKeys::SuperSet) {
529  // reference segment superset of current: discard
530  ATH_MSG_DEBUG(" discarding (subset) ");
531  isDuplicate = true;
532  break;
533  }
534  }
535  if (isDuplicate) segments->erase(skit->second);
536  }
537  }
538 
539  std::vector<std::unique_ptr<Trk::Track> > MooTrackBuilder::combineWithSegmentFinding(const EventContext& ctx, const MuPatTrack& candidate,
540  const Trk::TrackParameters& pars,
541  const std::set<Identifier>& chIds,
542  const PrepVec& externalPhiHits) const {
543  std::vector<std::unique_ptr<Trk::Track> > newTracks;
544 
545  if (chIds.empty()) return newTracks;
546 
547  if (!m_idHelperSvc->isMdt(*chIds.begin())) {
548  ATH_MSG_WARNING("combineWithSegmentFinding called with CSC hits!! retuning zero pointer");
549  return newTracks;
550  }
551 
552  // redo segment finding
553  std::unique_ptr<Trk::SegmentCollection> segments = m_seededSegmentFinder->find(ctx, pars, chIds);
554 
555  // check whether we got segments
556  if (!segments) {
557  ATH_MSG_DEBUG(" failed to find new segments ");
558  return newTracks;
559  }
560  if (segments->empty()) {
561  ATH_MSG_DEBUG(" got empty vector!! ");
562  return newTracks;
563  }
564 
565  unsigned int nseg = segments->size();
566  if (m_useExclusionList) {
567  std::vector<const MuonSegment*> referenceSegments;
568  for (std::vector<MuPatSegment*>::const_iterator esit = candidate.excludedSegments().begin();
569  esit != candidate.excludedSegments().end(); ++esit) {
570  if ((*esit)->segment) referenceSegments.push_back((*esit)->segment);
571  }
572  removeDuplicateWithReference(segments, referenceSegments);
573  }
574 
575  if (msgLvl(MSG::DEBUG) && segments->size() != nseg) {
577  << " Rejected segments based on exclusion list, number of removed segments: " << nseg - segments->size()
578  << " total " << segments->size() << endmsg;
579  }
580 
581  if (!segments->empty()) {
582  // loop over segments
583  for (Trk::Segment* tseg : *segments) {
584  if (!tseg) continue;
585  MuonSegment* mseg = dynamic_cast<MuonSegment*>(tseg);
586 
587  if (msgLvl(MSG::DEBUG)) {
588  msg(MSG::DEBUG) << MSG::DEBUG << " adding segment " << m_printer->print(*mseg);
589  if (msgLvl(MSG::VERBOSE)) {
590  msg(MSG::DEBUG) << std::endl << m_printer->print(mseg->containedMeasurements()) << endmsg;
591  if (msgLvl(MSG::VERBOSE) && candidate.track().measurementsOnTrack())
592  msg(MSG::DEBUG) << " track " << m_printer->print(candidate.track()) << std::endl
593  << m_printer->print(candidate.track().measurementsOnTrack()->stdcont()) << endmsg;
594  } else {
595  msg(MSG::DEBUG) << endmsg;
596  }
597  }
598  std::unique_ptr<MuPatSegment> segInfo{m_candidateHandler->createSegInfo(ctx, *mseg)};
599 
600  if (!m_candidateMatchingTool->match(ctx, candidate, *segInfo, true)) { continue; }
601 
602  std::unique_ptr<Trk::Track> segTrack = m_fitter->fit(ctx, candidate, *segInfo, externalPhiHits);
603 
604  if (!segTrack) continue;
605 
606  ATH_MSG_DEBUG(" found new track " << m_printer->print(*segTrack));
607  newTracks.push_back(std::move(segTrack));
608  }
609  }
610 
611  if (!newTracks.empty()) ATH_MSG_DEBUG(" found new tracks for segment " << newTracks.size());
612 
613  return newTracks;
614  }
615 
616  std::unique_ptr<Trk::Track> MooTrackBuilder::recalibrateHitsOnTrack(const EventContext& ctx, const Trk::Track& track, bool doMdts,
617  bool doCompetingClusters) const {
618  // loop over track and calculate residuals
619  const Trk::TrackStates* states = track.trackStateOnSurfaces();
620  if (!states) {
621  ATH_MSG_DEBUG(" track without states, discarding track ");
622  return nullptr;
623  }
624  if (msgLvl(MSG::DEBUG)) {
625  msg(MSG::DEBUG) << MSG::DEBUG << " recalibrating hits on track " << std::endl << m_printer->print(track);
626 
627  if (msgLvl(MSG::VERBOSE)) {
628  if (track.measurementsOnTrack())
629  msg(MSG::DEBUG) << std::endl << m_printer->print(track.measurementsOnTrack()->stdcont()) << endmsg;
630  } else {
631  msg(MSG::DEBUG) << endmsg;
632  }
633  }
634  // vector to store states, the boolean indicated whether the state was create in this routine (true) or belongs to the track (false)
635  // If any new state is created, all states will be cloned and a new track will beformed from them.
636  std::vector<std::unique_ptr<const Trk::TrackStateOnSurface>> newStates;
637  newStates.reserve(states->size() + 5);
638 
639  // loop over TSOSs
640  Trk::TrackStates::const_iterator state_itr = states->begin();
641  Trk::TrackStates::const_iterator end_itr = states->end();
642  for (; state_itr != end_itr; ++state_itr) {
643  const Trk::TrackStateOnSurface* tsit = (*state_itr);
644  if (!tsit) continue; // sanity check
645 
646  // check whether state is a measurement
647  const Trk::TrackParameters* pars = tsit->trackParameters();
648  if (!pars) {
649  newStates.emplace_back(tsit->clone());
650  continue;
651  }
652 
653  // check whether state is a measurement
654  const Trk::MeasurementBase* meas = tsit->measurementOnTrack();
655  if (!meas) {
656  newStates.emplace_back(tsit->clone());
657  continue;
658  }
659 
660  Identifier id = m_edmHelperSvc->getIdentifier(*meas);
661 
662  // Not a ROT, else it would have had an identifier. Keep the TSOS.
663  if (!id.is_valid() || !m_idHelperSvc->isMuon(id)) {
664  newStates.emplace_back(tsit->clone());
665  continue;
666  }
667 
668  ATH_MSG_VERBOSE(" new measurement " << m_idHelperSvc->toString(id));
669 
670  if (m_idHelperSvc->isMdt(id)) {
671  if (doMdts) {
672  const MdtDriftCircleOnTrack* mdt = dynamic_cast<const MdtDriftCircleOnTrack*>(meas);
673  if (!mdt) {
674  ATH_MSG_WARNING(" Measurement with MDT identifier that is not a MdtDriftCircleOnTrack ");
675  continue;
676  }
677  std::unique_ptr<Trk::RIO_OnTrack> newMdt(m_mdtRotCreator->correct(*mdt->prepRawData(), *pars, ctx));
678  if (!newMdt) {
679  ATH_MSG_WARNING(" Failed to recalibrate MDT ");
680  continue;
681  }
682  std::unique_ptr<Trk::TrackStateOnSurface> tsos = MuonTSOSHelper::createMeasTSOSWithUpdate(
683  *tsit, std::move(newMdt), pars->uniqueClone(),
686  newStates.push_back(std::move(tsos));
687 
688  } else {
689  newStates.emplace_back(tsit->clone());
690  }
691 
692  } else if (m_idHelperSvc->isCsc(id)) {
693  newStates.emplace_back(tsit->clone());
694 
695  } else if (m_idHelperSvc->isTrigger(id)) {
696  if (doCompetingClusters) {
697  state_itr = insertClustersWithCompetingRotCreation(ctx, state_itr, end_itr, newStates);
698  } else {
699  newStates.emplace_back(tsit->clone());
700  }
701 
702  } else if (m_idHelperSvc->isMM(id) || m_idHelperSvc->issTgc(id)) {
703  newStates.emplace_back(tsit->clone());
704  } else {
705  ATH_MSG_WARNING(" unknown Identifier ");
706  }
707  }
708 
709  ATH_MSG_DEBUG(" original track had " << states->size() << " TSOS, adding " << newStates.size() - states->size() << " new TSOS ");
710 
711  // states were added, create a new track
712  auto trackStateOnSurfaces = std::make_unique<Trk::TrackStates>();
713  trackStateOnSurfaces->reserve(newStates.size());
714  for (std::unique_ptr<const Trk::TrackStateOnSurface>& new_state : newStates) {
715  // add states. If nit->first is true we have a new state. If it is false the state is from the old track and has to be cloned
716  trackStateOnSurfaces->push_back(std::move(new_state));
717  }
718  return std::make_unique<Trk::Track>(track.info(), std::move(trackStateOnSurfaces),
719  track.fitQuality() ? track.fitQuality()->uniqueClone() : nullptr);
720  }
721 
725  std::vector<std::unique_ptr<const Trk::TrackStateOnSurface> >& states) const {
726  // iterator should point to a valid element
727  if (tsit == tsit_end) {
728  ATH_MSG_WARNING(" iterator pointing to end of vector, this should no happen ");
729  return --tsit;
730  }
731 
732  // check whether state is a measurement
733  const Trk::MeasurementBase* meas = (*tsit)->measurementOnTrack();
734  const Trk::TrackParameters* pars = (*tsit)->trackParameters();
735  if (!meas || !pars) {
736  ATH_MSG_WARNING(" iterator pointing to a TSOS without a measurement or TrackParameters ");
737  if (tsit + 1 == tsit_end) --tsit;
738  return tsit;
739  }
740 
741  ATH_MSG_VERBOSE(" inserting with competing ROT creation ");
742 
743  // loop over states until we reached the last tgc hit in this detector element
744  // keep trackof the identifiers and the states
745  std::list<const Trk::PrepRawData*> etaPrds;
746  std::list<const Trk::PrepRawData*> phiPrds;
747  const Trk::TrkDetElementBase* currentDetEl = nullptr;
748  std::vector<std::unique_ptr<const Trk::TrackStateOnSurface> > newStates;
749  // keep track of outliers as we might have to drop them..
750  std::vector<std::pair<bool, const Trk::TrackStateOnSurface*> > outlierStates;
751  bool hasPhi {false}, hasEta{false};
752 
753  for (; tsit != tsit_end; ++tsit) {
754  const Trk::TrackStateOnSurface* in_tsos = *tsit;
755  if (!in_tsos) continue;
756 
757  // check whether state is a measurement, keep if not
758  const Trk::MeasurementBase* meas = in_tsos->measurementOnTrack();
759  if (!meas) {
760  newStates.emplace_back(in_tsos->clone());
761  continue;
762  }
763 
764  // get identifier, keep state if it has no identifier.
765  Identifier id = m_edmHelperSvc->getIdentifier(*meas);
766  if (!id.is_valid()) {
767  newStates.emplace_back(in_tsos->clone());
768  continue;
769  }
770 
771  // sanity check, this SHOULD be a RPC, TGC or CSC measurement
772  if (!(m_idHelperSvc->isTrigger(id))) { break; }
773 
774  bool measuresPhi = m_idHelperSvc->measuresPhi(id);
775  if (!hasPhi && measuresPhi) hasPhi = true;
776  if (!hasEta && !measuresPhi) hasEta = true;
777 
778  // check whether state is a measurement
779  if ((*tsit)->type(Trk::TrackStateOnSurface::Outlier)) {
780  outlierStates.emplace_back(measuresPhi, in_tsos);
781  continue;
782  }
783 
784  // check whether we are still in the same chamber, stop loop if not
785 
786  ATH_MSG_VERBOSE(" handling " << m_idHelperSvc->toString(id));
787 
788  std::list<const Trk::PrepRawData*>& prdList = measuresPhi ? phiPrds : etaPrds;
789  const MuonClusterOnTrack* clus = dynamic_cast<const MuonClusterOnTrack*>(meas);
790  if (clus) {
791  const Trk::TrkDetElementBase* detEl = clus->detectorElement();
792  if (!currentDetEl) currentDetEl = detEl;
793  if (detEl != currentDetEl) {
794  ATH_MSG_VERBOSE(" new detector element stopping ");
795  break;
796  }
797  prdList.push_back(clus->prepRawData());
798  } else {
799  // split competing ROTs into constituents
800  const CompetingMuonClustersOnTrack* comp = dynamic_cast<const CompetingMuonClustersOnTrack*>(meas);
801  if (comp) {
802  const Trk::TrkDetElementBase* detEl = nullptr;
803  if (comp->containedROTs().empty()) {
804  ATH_MSG_WARNING(" CompetingROT without constituents ");
805  break;
806  }
807  detEl = comp->containedROTs().front()->detectorElement();
808  if (!currentDetEl) currentDetEl = detEl;
809  if (detEl != currentDetEl) {
810  ATH_MSG_VERBOSE(" new detector element stopping ");
811  break;
812  }
813  std::vector<const MuonClusterOnTrack*>::const_iterator clit = comp->containedROTs().begin();
814  std::vector<const MuonClusterOnTrack*>::const_iterator clit_end = comp->containedROTs().end();
815  for (; clit != clit_end; ++clit) { prdList.push_back((*clit)->prepRawData()); }
816 
817  } else {
818  ATH_MSG_WARNING(" Unknown trigger hit type! ");
819  continue;
820  }
821  }
822  }
823 
824  // now that we have the lists of prds we can create the competing rots
825  if (!etaPrds.empty()) {
826  std::unique_ptr<CompetingMuonClustersOnTrack> etaCompRot = m_compRotCreator->createBroadCluster(etaPrds, 0.);
827  if (!etaCompRot) {
828  ATH_MSG_WARNING(" Failed to create CompetingMuonClustersOnTrack for eta hits! ");
829  } else {
830  std::unique_ptr<Trk::TrackParameters> etaPars;;
831  // check whether original parameters are on surface, if so clone original parameters
832  if (etaCompRot->associatedSurface() == pars->associatedSurface()) {
833  etaPars = pars->uniqueClone();
834  } else {
835  // ownership relinquished, should be treated in createMeasTSOS
836  etaPars =
837  m_propagator->propagate(ctx,*pars,
838  etaCompRot->associatedSurface(),
840  }
841  if (!etaPars) {
842  ATH_MSG_WARNING(" Failed to calculate TrackParameters for eta hits! ");
843  } else {
844  std::unique_ptr<Trk::TrackStateOnSurface> tsos =
845  MuonTSOSHelper::createMeasTSOS(std::move(etaCompRot), std::move(etaPars), Trk::TrackStateOnSurface::Measurement);
846  newStates.push_back(std::move(tsos));
847  }
848  }
849  }
850 
851  if (!phiPrds.empty()) {
852  std::unique_ptr<CompetingMuonClustersOnTrack> phiCompRot = m_compRotCreator->createBroadCluster(phiPrds, 0.);
853  if (!phiCompRot) {
854  ATH_MSG_WARNING(" Failed to create CompetingMuonClustersOnTrack for phi hits! ");
855  } else {
856  std::unique_ptr<Trk::TrackParameters> phiPars;
857  // check whether original parameters are on surface, if so clone original parameters
858  if (phiCompRot->associatedSurface() == pars->associatedSurface()) {
859  phiPars = pars->uniqueClone();
860  } else {
861  // ownership relinquished, handled in createMeasTSOS
862  phiPars =
863  m_propagator->propagate(ctx, *pars, phiCompRot->associatedSurface(),
865  }
866  if (!phiPars) {
867  ATH_MSG_WARNING(" Failed to calculate TrackParameters for phi hits! ");
868  } else {
869  std::unique_ptr<Trk::TrackStateOnSurface> tsos =
870  MuonTSOSHelper::createMeasTSOS(std::move(phiCompRot), std::move(phiPars), Trk::TrackStateOnSurface::Measurement);
871  newStates.push_back(std::move(tsos));
872  }
873  }
874  }
875 
876  // add outliers if there was no measurement on track in the same projection
877  for (const auto& outlier : outlierStates) {
878  if (hasPhi && outlier.first)
879  newStates.emplace_back(outlier.second->clone());
880  else if (hasEta && !outlier.first)
881  newStates.emplace_back(outlier.second->clone());
882  else if (msgLvl(MSG::DEBUG))
883  msg(MSG::DEBUG) << " Dropping outlier " << endmsg;
884  }
885 
886  // sort all states in this chamber
887  std::stable_sort(newStates.begin(), newStates.end(), SortTSOSByDistanceToPars(pars));
888 
889  // insert the states into
890  states.insert(states.end(), std::make_move_iterator(newStates.begin()),
891  std::make_move_iterator(newStates.end()));
892 
893  // iterator should point to the last TGC in this chamber
894  return --tsit;
895  }
896 
897  std::pair<std::unique_ptr<Trk::Track>, std::unique_ptr<Trk::Track> > MooTrackBuilder::splitTrack(const EventContext& ctx, const Trk::Track& track) const {
898  // use slFitter for straight line fit, or toroid off, otherwise use normal Fitter
899 
900  if (m_edmHelperSvc->isSLTrack(track)) return m_slFitter->splitTrack(ctx, track);
901 
902  MagField::AtlasFieldCache fieldCache;
903  // Get field cache object
905  const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
906 
907  if (!fieldCondObj) {
908  ATH_MSG_ERROR("splitTrack: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCacheCondObjInputKey.key());
909  return {};
910  }
911  fieldCondObj->getInitializedCache(fieldCache);
912 
913  if (!fieldCache.toroidOn()) return m_slFitter->splitTrack(ctx, track);
914 
915  return m_fitter->splitTrack(ctx, track);
916  }
917 
918  std::vector<std::unique_ptr<MuPatTrack> > MooTrackBuilder::find(const EventContext& ctx, MuPatCandidateBase& candidate,
919  const std::vector<MuPatSegment*>& segVec) const {
920  std::vector<std::unique_ptr<MuPatTrack> > candidates;
921  // check whether we have segments
922  if (segVec.empty()) return candidates;
923 
924  std::set<MuPatSegment*> usedSegments;
925  std::map<MuPatSegment*, MuPatSegment*> slSegments;
926 
927  // int looseQualityLevel = 1; // Not used for the moment
928  bool tightQualityCuts = false;
929  ATH_MSG_DEBUG(" find: " << m_candidateHandler->print(candidate, 0) << std::endl << m_candidateHandler->print(segVec, 0));
930 
931  // store whether segment was added to at least one candidates
932 
933  // vector to store candidate extensions
934  std::vector<std::pair<MuPatSegment*, std::unique_ptr<Trk::Track> > > extensions;
935  extensions.reserve(segVec.size());
936 
937  // loop over segments
938  for (MuPatSegment* seg : segVec) {
939  if (usedSegments.count(seg)) continue;
940 
941  // check whether chamber is already included in candidate
942  if (candidate.shareChambers(*seg)) {
943  ATH_MSG_VERBOSE("addStationToSeed:: already on candidate " << std::endl << m_printer->print(*seg->segment));
944  continue;
945  }
946 
947  if (!m_candidateMatchingTool->match(ctx, candidate, *seg, tightQualityCuts)) {
948  ATH_MSG_VERBOSE(" track/segment combination rejected based on angular matching " << std::endl
949  << m_printer->print(*seg->segment));
950  continue;
951  }
952 
953  ATH_MSG_VERBOSE("combining: " << m_printer->print(*seg->segment));
954 
955  // try to combine track with segment
956  std::unique_ptr<Trk::Track> track = combine(ctx, candidate, *seg, emptyPhiHits);
957 
958  // additional check in case the candidate is a MuPatTrack
959  MuPatTrack* trkCan = dynamic_cast<MuPatTrack*>(&candidate);
960  MuPatSegment* segCan = dynamic_cast<MuPatSegment*>(&candidate);
961  if (trkCan) {
962  if (!track) {
963  trkCan->addExcludedSegment(seg);
964  continue;
965  }
966 
967  // is the new track better
969  if (!sortTracks(*track, trkCan->track())) {
970  ATH_MSG_VERBOSE(" rejecting track as new segment results in worse fit");
971  continue;
972  }
973 
974  // check whether the track cleaner didn't remove one of the already added chamber layers
975  // loop over hits
976  std::set<MuonStationIndex::StIndex> stationLayersOnTrack;
977  for ( const Trk::MeasurementBase* meas : *track->measurementsOnTrack()) {
978  Identifier id = m_edmHelperSvc->getIdentifier(*meas);
979  if (!id.is_valid() || m_idHelperSvc->isTrigger(id)) { continue; }
980  stationLayersOnTrack.insert(m_idHelperSvc->stationIndex(id));
981  }
982 
983  bool hasAllLayers = true;
984  for (const MuonStationIndex::StIndex& stIdx :candidate.stations()) {
985  if (!stationLayersOnTrack.count(stIdx)) {
986  ATH_MSG_VERBOSE(" missing layer " << MuonStationIndex::stName(stIdx));
987  hasAllLayers = false;
988  }
989  }
990 
991  if (!hasAllLayers) {
992  ATH_MSG_VERBOSE(" rejecting track as one of the chamber layers of the candidate was removed ");
993  continue;
994  }
995  }
996 
997  if (!track) { continue; }
998 
999  usedSegments.insert(seg);
1000 
1001  // now loop over segments once more and try to add SL overlap if missed
1002  // first check that segment is not an overlap segment
1003  if (!seg->hasSLOverlap()) {
1004  std::unique_ptr<MuPatTrack> newCandidate;
1005  // loop over segments
1006  for (MuPatSegment* seg_1 : segVec) {
1007  // select segments is different chamber
1008  if (seg->chIndex == seg_1->chIndex) continue;
1009 
1010  if (!newCandidate) {
1011  std::unique_ptr<Trk::Track> trkTrkCan = std::make_unique<Trk::Track>(*track);
1012  if (trkCan) {
1013  // copy candidate and add segment
1014  newCandidate = std::make_unique<MuPatTrack>(*trkCan);
1015  m_candidateHandler->extendWithSegment(*newCandidate, *seg, trkTrkCan);
1016  } else if (segCan) {
1017  newCandidate = m_candidateHandler->createCandidate(*segCan, *seg, trkTrkCan);
1018  }
1019  if (!newCandidate) break;
1020  }
1021  if (!m_candidateMatchingTool->match(ctx, *newCandidate, *seg_1, tightQualityCuts)) {
1022  ATH_MSG_VERBOSE("track/segment combination rejected based on angular matching "
1023  << std::endl
1024  << m_printer->print(*seg->segment));
1025  continue;
1026  }
1027 
1028  ATH_MSG_VERBOSE("adding SL overlap " << m_printer->print(*seg_1->segment));
1029  std::unique_ptr<Trk::Track> slOverlapTrack = combine(ctx, *track, *seg_1->segment, emptyPhiHits);
1030  if (!slOverlapTrack) continue;
1031 
1032  // is the new track better
1034  if (!sortTracks(*slOverlapTrack, *track)) {
1035  ATH_MSG_VERBOSE(__FILE__<<":"<<__LINE__<<" rejecting track as new segment results in worse fit");
1036  continue;
1037  }
1038  ATH_MSG_VERBOSE("adding SL overlap ok, new track" << m_printer->print(*slOverlapTrack) << std::endl
1039  << m_printer->printStations(*slOverlapTrack));
1040 
1041  track.swap(slOverlapTrack);
1042  usedSegments.insert(seg_1);
1043  slSegments[seg] = seg_1;
1044  break;
1045  }
1046  }
1047 
1048  ATH_MSG_VERBOSE(" Track found " << m_printer->print(*track)<<std::endl<<m_printer->printMeasurements(*track));
1049 
1050  // add new solution
1051  extensions.emplace_back(seg, std::move(track));
1052 
1053  } // for (sit)
1054 
1055  // loop over solutions and add them
1056  if (!extensions.empty()) {
1057  candidates.reserve(extensions.size());
1058 
1059  // additional check in case the candidate is a MuPatTrack
1060  MuPatTrack* trkCan = dynamic_cast<MuPatTrack*>(&candidate);
1061  MuPatSegment* segCan = dynamic_cast<MuPatSegment*>(&candidate);
1062 
1063  // if more than 1 extensions are found, first add the copies
1064  // start from the second one to make copies based on the existing candidates
1065  for (std::pair<MuPatSegment*, std::unique_ptr<Trk::Track> >& ext_itr : extensions) {
1066  std::unique_ptr<MuPatTrack> newCandidate;
1067  if (trkCan) {
1068  // copy candidate and add segment
1069  newCandidate = std::make_unique<MuPatTrack>(*trkCan);
1070  m_candidateHandler->extendWithSegment(*newCandidate, *ext_itr.first, ext_itr.second);
1071  } else if (segCan) {
1072  newCandidate = m_candidateHandler->createCandidate(*segCan, *ext_itr.first, ext_itr.second);
1073  }
1074  ATH_MSG_DEBUG(" " << m_printer->print(*ext_itr.first->segment));
1075  MuPatSegment* slOverlap = slSegments[ext_itr.first];
1076 
1077  if (slOverlap) {
1078  ATH_MSG_DEBUG("SLOverlap " << m_printer->print(*slOverlap->segment));
1079  // hack to allow me to add a second segment without changing the track
1080  std::unique_ptr<Trk::Track> nullTrack;
1081  newCandidate->addSegment(slOverlap, nullTrack);
1082  }
1083  candidates.push_back(std::move(newCandidate));
1084 
1085  ATH_MSG_DEBUG(" creating new candidate " << candidates.back().get() << std::endl
1086  << m_printer->print(candidates.back()->track()) << std::endl
1087  << m_printer->printStations(candidates.back()->track()));
1088  }
1089  }
1090  return candidates;
1091  }
1092 
1093  bool MooTrackBuilder::isSplitTrack(const EventContext& ctx, const Trk::Track& track1, const Trk::Track& track2) const {
1094  // some loose association cuts
1095  const DataVector<const Trk::TrackParameters>* parsVec1 = track1.trackParameters();
1096  if (!parsVec1 || parsVec1->empty()) {
1097  ATH_MSG_WARNING(" isSplitTrack::Track without parameters! ");
1098  return false;
1099  }
1100  const Trk::TrackParameters* pars1 = parsVec1->front();
1101  if (!pars1) {
1102  ATH_MSG_WARNING(" isSplitTrack::Track without NULL pointer in parameter vector! ");
1103  return false;
1104  }
1105 
1106  const DataVector<const Trk::TrackParameters>* parsVec2 = track2.trackParameters();
1107  if (!parsVec2 || parsVec2->empty()) {
1108  ATH_MSG_WARNING(" isSplitTrack::Track without parameters! ");
1109  return false;
1110  }
1111  const Trk::TrackParameters* pars2 = parsVec2->front();
1112  if (!pars2) {
1113  ATH_MSG_WARNING(" isSplitTrack::Track without NULL pointer in parameter vector! ");
1114  return false;
1115  }
1116 
1117  if (!m_candidateMatchingTool->sameSide(pars1->momentum().unit(), pars1->position(), pars2->position(), true)) {
1118  ATH_MSG_DEBUG(" tracks in opposite hemispheres ");
1119  return false;
1120  }
1121 
1122  double sinTheta1 = sin(pars1->momentum().theta());
1123  double sinTheta2 = sin(pars2->momentum().theta());
1124  double deltaSinTheta = sinTheta1 - sinTheta2;
1125  if (std::abs(deltaSinTheta) > 1.) {
1126  ATH_MSG_DEBUG(" too large opening angle in theta " << deltaSinTheta);
1127  // return false;
1128  }
1129  double sinPhi1 = sin(pars1->momentum().phi());
1130  double sinPhi2 = sin(pars2->momentum().phi());
1131  double deltaSinPhi = sinPhi1 - sinPhi2;
1132  if (std::abs(deltaSinPhi) > 1.) {
1133  ATH_MSG_DEBUG(" too large opening angle in phi " << deltaSinPhi);
1134  // return false;
1135  }
1136 
1137  const Trk::Track* referenceTrack = nullptr;
1138  const Trk::Track* otherTrack = nullptr;
1139 
1140  // first check whether the tracks have a momentum measurement
1141  bool isSL1 = m_edmHelperSvc->isSLTrack(track1);
1142  bool isSL2 = m_edmHelperSvc->isSLTrack(track2);
1143 
1144  // now decide which track to use as reference
1145  if (isSL1 && !isSL2) {
1146  referenceTrack = &track2;
1147  otherTrack = &track1;
1148  } else if (!isSL1 && isSL2) {
1149  referenceTrack = &track1;
1150  otherTrack = &track2;
1151  } else {
1153  bool pickFirst = sortTracks(track1, track2);
1154  if (pickFirst) {
1155  referenceTrack = &track1;
1156  otherTrack = &track2;
1157  } else {
1158  referenceTrack = &track2;
1159  otherTrack = &track1;
1160  }
1161  }
1162 
1163  ATH_MSG_DEBUG(" close tracks " << std::endl << m_printer->print(*referenceTrack) << std::endl << m_printer->print(*otherTrack));
1164 
1165  // get iterators to TSOSs
1166  const Trk::TrackStates* statesRef = referenceTrack->trackStateOnSurfaces();
1167  if (!statesRef) {
1168  ATH_MSG_WARNING(" track without states, cannot perform cleaning ");
1169  return false;
1170  }
1171  Trk::TrackStates::const_iterator refTSOS = statesRef->begin();
1172  Trk::TrackStates::const_iterator refTSOS_end = statesRef->end();
1173 
1174  const Trk::TrackStates* statesOther = otherTrack->trackStateOnSurfaces();
1175  if (!statesOther) {
1176  ATH_MSG_WARNING(" track without states, cannot perform cleaning ");
1177  return false;
1178  }
1179  Trk::TrackStates::const_iterator otherTSOS = statesOther->begin();
1180  Trk::TrackStates::const_iterator otherTSOS_end = statesOther->end();
1181 
1182  DistanceAlongParameters distAlongPars;
1183 
1184  unsigned int nmatching(0);
1185  unsigned int noff(0);
1186 
1187  // keep track of previous distance and parameters as well
1188  double prevDist = 1e10;
1189  const Trk::TrackParameters* prevPars = nullptr;
1190 
1191  // now loop over the TSOSs of both tracks and compare hit by hit
1192  while (refTSOS != refTSOS_end && otherTSOS != otherTSOS_end) {
1193  const Trk::TrackParameters* parsRef = (*refTSOS)->trackParameters();
1194  if (!parsRef) {
1195  ++refTSOS;
1196  continue;
1197  }
1198 
1199  const Trk::TrackParameters* parsOther = (*otherTSOS)->trackParameters();
1200  if (!parsOther) {
1201  ++otherTSOS;
1202  continue;
1203  }
1204 
1205  double dist = distAlongPars(*parsRef, *parsOther);
1206 
1207  if (dist > 0.) {
1208  prevDist = dist;
1209  prevPars = parsRef;
1210  ++refTSOS;
1211  continue;
1212  } else {
1213  const Trk::TrackParameters* closestPars = nullptr;
1214  if (prevPars && std::abs(prevDist) < std::abs(dist)) {
1215  closestPars = prevPars;
1216  } else {
1217  closestPars = parsRef;
1218  }
1219 
1220  // check whether state is a measurement
1221  const Trk::MeasurementBase* meas = (*otherTSOS)->measurementOnTrack();
1222  if (meas && (*otherTSOS)->type(Trk::TrackStateOnSurface::Measurement)) {
1223  Identifier id = m_edmHelperSvc->getIdentifier(*meas);
1224  // skip pseudo measurements
1225  if (!id.is_valid()) {
1226  prevDist = dist;
1227  prevPars = parsRef;
1228  ++otherTSOS;
1229  continue;
1230  }
1231  if (msgLvl(MSG::VERBOSE)) msg(MSG::VERBOSE) << m_idHelperSvc->toString(id);
1232  // unique ptr ownership retained. Original code deleted impactPars
1233  auto impactPars =
1234  m_propagator->propagate(ctx, *closestPars, meas->associatedSurface(),
1236  if (impactPars) {
1237  double residual = 1e10;
1238  double pull = 1e10;
1239  // pointer to resPull
1240  std::optional<Trk::ResidualPull> resPull =
1241  m_pullCalculator->residualPull(meas, impactPars.get(), Trk::ResidualPull::Unbiased);
1242  if (resPull && resPull->pull().size() == 1) {
1243  if (msgLvl(MSG::VERBOSE)) msg(MSG::VERBOSE) << " residual " << m_printer->print(*resPull);
1244  residual = resPull->residual().front();
1245  pull = resPull->pull().front();
1246  } else {
1247  ATH_MSG_WARNING("failed to calculate residual and pull");
1248  }
1249 
1250  bool inBounds = false;
1251  Amg::Vector2D LocVec2D;
1252  bool ok = meas->associatedSurface().globalToLocal(impactPars->position(), impactPars->momentum(), LocVec2D);
1253  // delete impactPars;
1254  if (ok) {
1255  if (msgLvl(MSG::VERBOSE))
1256  msg(MSG::VERBOSE) << " lpos (" << LocVec2D[Trk::locX] << "," << LocVec2D[Trk::locY] << ")";
1257  double tol1 = 50.;
1258  double tol2 = tol1;
1259  Identifier id = m_edmHelperSvc->getIdentifier(*meas);
1260  if (msgLvl(MSG::VERBOSE) && m_idHelperSvc->isMdt(id)) {
1261  const MdtDriftCircleOnTrack* mdt = dynamic_cast<const MdtDriftCircleOnTrack*>(meas);
1262  if (mdt) {
1263  int layer = m_idHelperSvc->mdtIdHelper().tubeLayer(id);
1264  int tube = m_idHelperSvc->mdtIdHelper().tube(id);
1265  double halfTubeLen = 0.5 * mdt->detectorElement()->getActiveTubeLength(layer, tube);
1266  if (msgLvl(MSG::VERBOSE)) msg(MSG::VERBOSE) << " range " << halfTubeLen;
1267  }
1268  }
1269 
1270  // for MM, perform the bound check from the detector element to take into account edge passivation
1271  const MMClusterOnTrack* mmClusterOnTrack = dynamic_cast<const MMClusterOnTrack*>(meas);
1272  if (mmClusterOnTrack) {
1273  inBounds = mmClusterOnTrack->detectorElement()->insideActiveBounds(id, LocVec2D, tol1, tol2);
1274  } else {
1275  inBounds = meas->associatedSurface().insideBounds(LocVec2D, tol1, tol2);
1276  }
1277 
1278  if (msgLvl(MSG::VERBOSE)) {
1279  if (inBounds)
1280  msg(MSG::VERBOSE) << " inBounds ";
1281  else
1282  msg(MSG::VERBOSE) << " outBounds ";
1283  }
1284  } else {
1285  ATH_MSG_WARNING("globalToLocal failed");
1286  }
1287 
1288  if (inBounds && (std::abs(residual) < 20. || std::abs(pull) < 10.)) {
1289  ATH_MSG_VERBOSE(" --> matching ");
1290  ++nmatching;
1291  } else {
1292  ATH_MSG_VERBOSE(" --> off ");
1293  ++noff;
1294  }
1295 
1296  } else {
1297  ATH_MSG_DEBUG("failed to extrapolate parameters to surface");
1298  }
1299  }
1300 
1301  prevDist = dist;
1302  prevPars = parsRef;
1303  ++otherTSOS;
1304  continue;
1305  }
1306  }
1307 
1308  // if more hits are compatible with reference track than are not consider as split track
1309  return nmatching > noff;
1310  }
1311 
1312  TrackCollection* MooTrackBuilder::mergeSplitTracks(const EventContext& ctx, const TrackCollection& tracks) const {
1313  // vector to store good track, boolean is used to identify whether the track was created in this routine or is from the collection
1314  std::vector<std::pair<bool, std::unique_ptr<Trk::Track> > > goodTracks;
1315  goodTracks.reserve(tracks.size());
1316  bool foundSplitTracks = false;
1317 
1318  ATH_MSG_DEBUG(" trying to merge split tracks, collection size " << tracks.size());
1319 
1320  // loop over tracks
1321  for (const Trk::Track* in_track : tracks) {
1322  // pointer to merged track
1323  std::unique_ptr<Trk::Track> mergedTrack;
1324 
1325  // compare them to all good tracks and look for split tracks
1326  for (std::pair<bool, std::unique_ptr<Trk::Track>>& good_trk : goodTracks) {
1327  // check whether track is split
1328  bool isSplit = isSplitTrack(ctx, *good_trk.second, *in_track);
1329  if (isSplit) {
1330  // if we found a potential split track, try to combine them
1331  std::unique_ptr<Trk::Track> track1 = std::make_unique<Trk::Track>(*good_trk.second);
1332  std::unique_ptr<Trk::Track> track2 = std::make_unique<Trk::Track>(*in_track);
1333  std::unique_ptr<MuPatTrack> can1 = m_candidateHandler->createCandidate(track1);
1334  std::unique_ptr<MuPatTrack> can2 = m_candidateHandler->createCandidate(track2);
1335  mergedTrack = combine(ctx, *can1, *can2, emptyPhiHits);
1336 
1337  // we have found a split track and have successfully merged it
1338  // replace the track in goodTracks with the new one
1339  if (mergedTrack) {
1340  ATH_MSG_DEBUG(" origninal tracks " << std::endl
1341  << m_printer->print(*good_trk.second) << std::endl
1342  << m_printer->printStations(*good_trk.second) << std::endl
1343  << m_printer->print(*in_track) << std::endl
1344  << m_printer->printStations(*in_track) << std::endl
1345  << " merged track " << std::endl
1346  << m_printer->print(*mergedTrack) << std::endl
1347  << m_printer->printStations(*mergedTrack));
1348  foundSplitTracks = true;
1349  // check whether this is a new track, if so delete the old one before overwriting it
1350  good_trk.first = true;
1351  good_trk.second.swap(mergedTrack);
1352  break;
1353  } else {
1354  ATH_MSG_VERBOSE(" failed to merge tracks " << std::endl
1355  << m_printer->print(*good_trk.second) << std::endl
1356  << m_printer->printStations(*good_trk.second) << std::endl
1357  << m_printer->print(*in_track) << std::endl
1358  << m_printer->printStations(*in_track));
1359  }
1360  }
1361  }
1362 
1363  // if this track was not merged with another track insert it into goodTracks
1364  if (!mergedTrack) {
1365  std::unique_ptr<Trk::Track> newTrack = std::make_unique<Trk::Track>(*in_track);
1366  goodTracks.emplace_back(false, std::move(newTrack));
1367  }
1368  }
1369 
1370  // did we find any?
1371  if (!foundSplitTracks) return nullptr;
1372  // loop over the new track vector and create a new TrackCollection
1373  TrackCollection* newTracks = new TrackCollection();
1374  newTracks->reserve(goodTracks.size());
1375  for (std::pair<bool, std::unique_ptr<Trk::Track>>& good_trk: goodTracks) {
1376  // TrackCollection will take ownership
1377  newTracks->push_back(std::move(good_trk.second));
1378  }
1379  return newTracks;
1380  }
1381 
1382 } // namespace Muon
DataVector::reserve
void reserve(size_type n)
Attempt to preallocate enough memory for a specified number of elements.
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
Muon::MooTrackBuilder::isSplitTrack
bool isSplitTrack(const EventContext &ctx, const Trk::Track &track1, const Trk::Track &track2) const
identify whether two track are split
Definition: MooTrackBuilder.cxx:1093
Trk::anyDirection
@ anyDirection
Definition: PropDirection.h:22
plotting.yearwise_luminosity_vs_mu.comp
comp
Definition: yearwise_luminosity_vs_mu.py:23
used
make_hlt_rep.pars
pars
Definition: make_hlt_rep.py:90
Trk::TrackStateOnSurface::trackParameters
const TrackParameters * trackParameters() const
return ptr to trackparameters const overload
DataModel_detail::const_iterator
Const iterator class for DataVector/DataList.
Definition: DVLIterator.h:82
Muon::MooTrackBuilder::m_muonChamberHoleRecoverTool
ToolHandle< IMuonHoleRecoveryTool > m_muonChamberHoleRecoverTool
Definition: MooTrackBuilder.h:277
Muon::MooTrackBuilder::mergeSplitTracks
TrackCollection * mergeSplitTracks(const EventContext &ctx, const TrackCollection &tracks) const
look for split tracks in collection and merge them
Definition: MooTrackBuilder.cxx:1312
MuonGM::MMReadoutElement::insideActiveBounds
bool insideActiveBounds(const Identifier &id, const Amg::Vector2D &locpos, double tol1=0., double tol2=0.) const
boundary check Wrapper Trk::PlaneSurface::insideBounds() taking into account the passivated width
Definition: MMReadoutElement.h:252
Muon::MooTrackBuilder::m_trackToSegmentTool
ToolHandle< IMuonTrackToSegmentTool > m_trackToSegmentTool
Definition: MooTrackBuilder.h:261
Muon::MuPatCandidateBase
track candidate entry object.
Definition: MuPatCandidateBase.h:46
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
Muon::MdtDriftCircleOnTrack::prepRawData
virtual const MdtPrepData * prepRawData() const override final
Returns the PrepRawData used to create this corrected measurement.
Definition: MdtDriftCircleOnTrack.h:257
Trk::locX
@ locX
Definition: ParamDefs.h:37
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
Trk::locY
@ locY
local cartesian
Definition: ParamDefs.h:38
Trk::Track
The ATLAS Track class.
Definition: Tracking/TrkEvent/TrkTrack/TrkTrack/Track.h:73
Muon::MooTrackBuilder::m_useTrackingHistory
Gaudi::Property< bool > m_useTrackingHistory
use history of the track finding up to now to avoid creating duplicates
Definition: MooTrackBuilder.h:293
AtlasFieldCacheCondObj
Definition: AtlasFieldCacheCondObj.h:19
ClusterSeg::residual
@ residual
Definition: ClusterNtuple.h:20
Trk::TrackStateOnSurface::clone
virtual TrackStateOnSurface * clone() const
Pseudo-constructor: needed to avoid excessive RTTI.
Trk::ParametersBase::position
const Amg::Vector3D & position() const
Access method for the position.
Amg::Vector2D
Eigen::Matrix< double, 2, 1 > Vector2D
Definition: GeoPrimitives.h:48
TRT_PAI_gasdata::EO
const float EO[NO]
Energy levels for Oxygen.
Definition: TRT_PAI_gasdata.h:301
drawFromPickle.candidates
candidates
Definition: drawFromPickle.py:271
Muon::MuonStationIndex::StIndex::EM
@ EM
Trk::ParametersBase::uniqueClone
std::unique_ptr< ParametersBase< DIM, T > > uniqueClone() const
clone method for polymorphic deep copy returning unique_ptr; it is not overriden, but uses the existi...
Definition: ParametersBase.h:97
Trk::Track::trackStateOnSurfaces
const Trk::TrackStates * trackStateOnSurfaces() const
return a pointer to a const DataVector of const TrackStateOnSurfaces.
Muon::MuonClusterOnTrack::prepRawData
virtual const MuonCluster * prepRawData() const override=0
Returns the Trk::PrepRawData - is a MuonCluster in this scope.
Muon::MooTrackBuilder::m_edmHelperSvc
ServiceHandle< IMuonEDMHelperSvc > m_edmHelperSvc
Definition: MooTrackBuilder.h:263
Muon::MooTrackBuilder::recalibrateHitsOnTrack
virtual std::unique_ptr< Trk::Track > recalibrateHitsOnTrack(const EventContext &ctx, const Trk::Track &track, bool doMdts, bool doCompetingClusters) const override
recalibrate hits on track
Definition: MooTrackBuilder.cxx:616
Muon::MuonGetClosestParameters::closestParameters
static std::unique_ptr< Trk::TrackParameters > closestParameters(const Trk::Track &track, const Amg::Vector3D &pos, bool onlyUseMeasured=false)
Definition: MuonGetClosestParameters.h:19
Muon::MuonStationIndex::stName
const std::string & stName(StIndex index)
convert StIndex into a string
Definition: MuonStationIndex.cxx:104
Muon::MuPatCandidateBase::shareChambers
bool shareChambers(const MuPatCandidateBase &entry) const
checks whether the two entries contain the same chamber
Definition: MuPatCandidateBase.cxx:20
Trk::ResidualPull::Unbiased
@ Unbiased
RP with track state that has measurement not included.
Definition: ResidualPull.h:57
skel.it
it
Definition: skel.GENtoEVGEN.py:407
Muon::MooTrackBuilder::refit
virtual std::unique_ptr< Trk::Track > refit(const EventContext &ctx, Trk::Track &track) const override
refit track
Definition: MooTrackBuilder.cxx:68
CompetingMuonClustersOnTrack.h
Muon::MooTrackBuilder::finalize
virtual StatusCode finalize() override
finialize method, method taken from bass-class AlgTool
Definition: MooTrackBuilder.cxx:60
AthCommonMsg< AlgTool >::msgLvl
bool msgLvl(const MSG::Level lvl) const
Definition: AthCommonMsg.h:30
Muon::MooTrackBuilder::m_candidateHandler
ToolHandle< MuPatCandidateTool > m_candidateHandler
candidate handler
Definition: MooTrackBuilder.h:257
Trk::TrackStateOnSurface::measurementOnTrack
const MeasurementBase * measurementOnTrack() const
returns MeasurementBase const overload
Muon::MuonSegmentKey
Class to cache the identifiers on a segment in sets that can later be used to perform an overlap remo...
Definition: MuonSegmentKey.h:24
Trk::TrkDetElementBase
Definition: TrkDetElementBase.h:52
InDetSecVtxTruthMatchUtils::isSplit
bool isSplit(int matchInfo)
Definition: InDetSecVtxTruthMatchTool.h:83
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
Muon::MdtDriftCircleOnTrack::detectorElement
virtual const MuonGM::MdtReadoutElement * detectorElement() const override final
Returns the detector element, assoicated with the PRD of this class.
Definition: MdtDriftCircleOnTrack.h:268
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
Muon::CompetingMuonClustersOnTrack
Definition: CompetingMuonClustersOnTrack.h:54
SG::VarHandleKey::key
const std::string & key() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:141
MdtDriftCircleOnTrack.h
MagField::AtlasFieldCache::toroidOn
bool toroidOn() const
Muon::MooTrackBuilder::m_seededSegmentFinder
ToolHandle< IMuonSeededSegmentFinder > m_seededSegmentFinder
Definition: MooTrackBuilder.h:268
Muon
NRpcCablingAlg reads raw condition data and writes derived condition data to the condition store.
Definition: TrackSystemController.h:45
yodamerge_tmp.scale
scale
Definition: yodamerge_tmp.py:138
MuPatSegment.h
Muon::MooTrackBuilder::m_compRotCreator
ToolHandle< IMuonCompetingClustersOnTrackCreator > m_compRotCreator
Definition: MooTrackBuilder.h:272
MMClusterOnTrack.h
Trk::TrackStateOnSurface::Outlier
@ Outlier
This TSoS contains an outlier, that is, it contains a MeasurementBase/RIO_OnTrack which was not used ...
Definition: TrackStateOnSurface.h:122
Muon::MuonClusterOnTrack::detectorElement
virtual const MuonGM::MuonClusterReadoutElement * detectorElement() const override=0
Returns the detector element, associated with the PRD of this class.
Muon::MooTrackBuilder::m_candidateMatchingTool
ToolHandle< MooCandidateMatchingTool > m_candidateMatchingTool
Definition: MooTrackBuilder.h:259
Muon::CompareMuonSegmentKeys::OverlapResult
OverlapResult
enum for the overlap result
Definition: CompareMuonSegmentKeys.h:16
Trk::TrackStateOnSurface::type
bool type(const TrackStateOnSurfaceType type) const
Use this method to find out if the TSoS is of a certain type: i.e.
MuonTSOSHelper.h
Muon::MooTrackBuilder::m_fitter
ToolHandle< MooTrackFitter > m_fitter
Definition: MooTrackBuilder.h:255
Muon::MooTrackBuilder::m_nTimedOut
std::atomic_uint m_nTimedOut
Definition: MooTrackBuilder.h:297
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:209
PlotPulseshapeFromCool.can
can
Definition: PlotPulseshapeFromCool.py:91
Muon::CompareMuonSegmentKeys::Identical
@ Identical
Definition: CompareMuonSegmentKeys.h:17
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
Muon::MooTrackBuilder::find
virtual std::vector< std::unique_ptr< MuPatTrack > > find(const EventContext &ctx, MuPatCandidateBase &candidate, const std::vector< MuPatSegment * > &segments) const override
interface for tools to find track in the muon system starting from a vector of segments
Definition: MooTrackBuilder.cxx:918
ResidualPull.h
Muon::MuPatSegment::entryPars
const Trk::TrackParameters & entryPars() const
returns first track parameters
Definition: MuPatSegment.h:84
Muon::MooTrackBuilder::m_trackExtrapolationTool
ToolHandle< IMuonTrackExtrapolationTool > m_trackExtrapolationTool
Definition: MooTrackBuilder.h:280
DataModel_detail::iterator
(Non-const) Iterator class for DataVector/DataList.
Definition: DVLIterator.h:184
TrackCollection
DataVector< Trk::Track > TrackCollection
This typedef represents a collection of Trk::Track objects.
Definition: TrackCollection.h:19
Muon::MooTrackBuilder::m_idHelperSvc
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
Definition: MooTrackBuilder.h:267
beamspotman.n
n
Definition: beamspotman.py:729
SortMuPatHits.h
Muon::MooTrackBuilder::getClosestParameters
virtual std::unique_ptr< Trk::TrackParameters > getClosestParameters(const Trk::Track &track, const Trk::Surface &surf) const override
find closest TrackParameters to the surface.
Definition: MooTrackBuilder.cxx:411
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
urldecode::states
states
Definition: urldecode.h:39
TRT::Hit::layer
@ layer
Definition: HitInfo.h:79
Muon::MooTrackBuilder::m_slFitter
ToolHandle< MooTrackFitter > m_slFitter
Definition: MooTrackBuilder.h:256
MuonGM::MdtReadoutElement::getActiveTubeLength
double getActiveTubeLength(const int tubeLayer, const int tube) const
Muon::MuonTSOSHelper::createMeasTSOS
static std::unique_ptr< Trk::TrackStateOnSurface > createMeasTSOS(std::unique_ptr< Trk::MeasurementBase > meas, std::unique_ptr< Trk::TrackParameters > pars, Trk::TrackStateOnSurface::TrackStateOnSurfaceType type)
create a TSOS with a measurement, takes ownership of the pointers
Definition: MuonTSOSHelper.h:62
Trk::Segment::containedMeasurements
const std::vector< const Trk::MeasurementBase * > & containedMeasurements() const
returns the vector of Trk::MeasurementBase objects
Definition: Tracking/TrkEvent/TrkSegment/TrkSegment/Segment.h:166
Trk::Segment
Definition: Tracking/TrkEvent/TrkSegment/TrkSegment/Segment.h:56
Muon::MooTrackBuilder::m_printer
PublicToolHandle< MuonEDMPrinterTool > m_printer
tool to print out EDM objects;
Definition: MooTrackBuilder.h:265
MuPatTrack.h
Muon::MuPatSegment::segment
const MuonSegment * segment
Definition: MuPatSegment.h:53
DataVector::front
const T * front() const
Access the first element in the collection as an rvalue.
Muon::MooTrackBuilder::m_ncalls
std::atomic_uint m_ncalls
Definition: MooTrackBuilder.h:296
Muon::MooTrackBuilder::m_trackSummaryTool
ToolHandle< Trk::IExtendedTrackSummaryTool > m_trackSummaryTool
Definition: MooTrackBuilder.h:284
Muon::SortTracksByHitNumber
Definition: SortTracksByHitNumber.h:15
python.StandardJetMods.pull
pull
Definition: StandardJetMods.py:304
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
Trk::MeasurementBase::type
virtual bool type(MeasurementBaseType::Type type) const =0
Interface method checking the type.
Muon::MooTrackBuilder::MooTrackBuilder
MooTrackBuilder(const std::string &, const std::string &, const IInterface *)
default AlgTool constructor
Definition: MooTrackBuilder.cxx:30
Muon::MooTrackBuilder::findClosestParameters
virtual std::unique_ptr< Trk::TrackParameters > findClosestParameters(const Trk::Track &track, const Amg::Vector3D &pos) const override
find closest TrackParameters to the position.
Definition: MooTrackBuilder.cxx:345
Trk::ParametersBase
Definition: ParametersBase.h:55
Muon::MuPatTrack::excludedSegments
const std::vector< MuPatSegment * > & excludedSegments() const
access to segments
Definition: MuPatTrack.h:173
Athena::Timeout::instance
static Timeout & instance()
Get reference to Timeout singleton.
Definition: Timeout.h:64
DataVector< const Trk::TrackStateOnSurface >
MooTrackBuilder.h
Muon::MooTrackBuilder::m_doTimeOutChecks
Gaudi::Property< bool > m_doTimeOutChecks
on/off time out check
Definition: MooTrackBuilder.h:290
SortMeasurementsByPosition.h
Muon::MooTrackBuilder::combine
std::unique_ptr< Trk::Track > combine(const EventContext &ctx, const MuPatCandidateBase &firstEntry, const MuPatCandidateBase &secondEntry, const PrepVec &patternPhiHits) const
combine two MCTBCandidateEntries
Definition: MooTrackBuilder.cxx:178
Muon::MuPatTrack::addExcludedSegment
void addExcludedSegment(MuPatSegment *segment)
add segment that does not match the track
Definition: MuPatTrack.cxx:212
Muon::MuonStationIndex::StIndex::BO
@ BO
Muon::MuonStationIndex::StIndex
StIndex
enum to classify the different station layers in the muon spectrometer
Definition: MuonStationIndex.h:23
Muon::MMClusterOnTrack
Class to represent calibrated clusters formed from TGC strips.
Definition: MMClusterOnTrack.h:26
Trk::MeasurementBase
Definition: MeasurementBase.h:58
Muon::MooTrackBuilder::m_recalibrateMDTHits
Gaudi::Property< bool > m_recalibrateMDTHits
Definition: MooTrackBuilder.h:295
Trk::Track::trackParameters
const DataVector< const TrackParameters > * trackParameters() const
Return a pointer to a vector of TrackParameters.
Definition: Tracking/TrkEvent/TrkTrack/src/Track.cxx:97
Trk::TrackStateOnSurface
represents the track state (measurement, material, fit parameters and quality) at a surface.
Definition: TrackStateOnSurface.h:71
Trk::MeasurementBase::associatedSurface
virtual const Surface & associatedSurface() const =0
Interface method to get the associated Surface.
Muon::MooTrackBuilder::m_useExclusionList
Gaudi::Property< bool > m_useExclusionList
use exclusion list (bit faster at the price of missing chambers)
Definition: MooTrackBuilder.h:291
Muon::MdtDriftCircleOnTrack
This class represents the corrected MDT measurements, where the corrections include the effects of wi...
Definition: MdtDriftCircleOnTrack.h:37
Muon::MooTrackBuilder::m_fieldCacheCondObjInputKey
SG::ReadCondHandleKey< AtlasFieldCacheCondObj > m_fieldCacheCondObjInputKey
Definition: MooTrackBuilder.h:286
Muon::MooTrackBuilder::combineToSegment
std::unique_ptr< MuonSegment > combineToSegment(const EventContext &ctx, const MuPatCandidateBase &firstEntry, const MuPatCandidateBase &secondEntry, const PrepVec &patternPhiHits) const
Methos is used externally by MuonTrackSteering.cxx:233. Should be revised to put it into an interface...
Definition: MooTrackBuilder.cxx:164
DataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
Muon::MooTrackBuilder::initialize
virtual StatusCode initialize() override
initialize method, method taken from bass-class AlgTool
Definition: MooTrackBuilder.cxx:37
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
plot.extensions
string extensions
Definition: PhysicsAnalysis/ElectronPhotonID/ElectronPhotonFourMomentumCorrection/python/plot.py:61
Trk::Surface::insideBounds
virtual bool insideBounds(const Amg::Vector2D &locpos, double tol1=0., double tol2=0.) const =0
virtual methods to be overwritten by the inherited surfaces
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
Muon::MuPatSegment
segment candidate object.
Definition: MuPatSegment.h:43
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:16
DataVector::end
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
Trk::Track::measurementsOnTrack
const DataVector< const MeasurementBase > * measurementsOnTrack() const
return a pointer to a vector of MeasurementBase (NOT including any that come from outliers).
Definition: Tracking/TrkEvent/TrkTrack/src/Track.cxx:178
Muon::MooTrackBuilder::splitTrack
std::pair< std::unique_ptr< Trk::Track >, std::unique_ptr< Trk::Track > > splitTrack(const EventContext &ctx, const Trk::Track &track) const
split given track if it crosses the calorimeter volume, code assumes that the track was already extra...
Definition: MooTrackBuilder.cxx:897
Timeout.h
Timeout singleton.
Trk::ParametersBase::momentum
const Amg::Vector3D & momentum() const
Access method for the momentum.
MuonGetClosestParameters.h
Muon::MooTrackBuilder::refine
virtual void refine(const EventContext &ctx, MuPatTrack &track) const override
interface for tools which refine the hit content of a given track
Definition: MooTrackBuilder.cxx:92
Muon::MuPatTrack::track
Trk::Track & track() const
access to track
Definition: MuPatTrack.h:175
Muon::MooTrackBuilder::m_errorOptimisationTool
ToolHandle< IMuonErrorOptimisationTool > m_errorOptimisationTool
Definition: MooTrackBuilder.h:283
Trk::Surface::globalToLocal
virtual bool globalToLocal(const Amg::Vector3D &glob, const Amg::Vector3D &mom, Amg::Vector2D &loc) const =0
Specified by each surface type: GlobalToLocal method without dynamic memory allocation - boolean chec...
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
Muon::MuPatTrack
track candidate object.
Definition: MuPatTrack.h:37
DEBUG
#define DEBUG
Definition: page_access.h:11
AthCommonMsg< AlgTool >::msg
MsgStream & msg() const
Definition: AthCommonMsg.h:24
MagField::AtlasFieldCache
Local cache for magnetic field (based on MagFieldServices/AtlasFieldSvcTLS.h)
Definition: AtlasFieldCache.h:43
Muon::SortTSOSByDistanceToPars
Definition: SortMeasurementsByPosition.h:55
Muon::MooTrackBuilder::m_magFieldProperties
Trk::MagneticFieldProperties m_magFieldProperties
magnetic field properties
Definition: MooTrackBuilder.h:288
Muon::MuonTSOSHelper::createMeasTSOSWithUpdate
static std::unique_ptr< Trk::TrackStateOnSurface > createMeasTSOSWithUpdate(const Trk::TrackStateOnSurface &tsos, std::unique_ptr< Trk::MeasurementBase > meas, std::unique_ptr< Trk::TrackParameters > pars, Trk::TrackStateOnSurface::TrackStateOnSurfaceType type)
create a TSOS with a measurement, takes ownership of the pointers
Definition: MuonTSOSHelper.h:74
Muon::MuonSegment::globalPosition
virtual const Amg::Vector3D & globalPosition() const override final
global position
Definition: MuonSpectrometer/MuonReconstruction/MuonRecEvent/MuonSegment/MuonSegment/MuonSegment.h:157
MuonClusterOnTrack.h
SortTracksByHitNumber.h
xAOD::track
@ track
Definition: TrackingPrimitives.h:513
python.Constants.VERBOSE
int VERBOSE
Definition: Control/AthenaCommon/python/Constants.py:13
Muon::MuonSegment
Definition: MuonSpectrometer/MuonReconstruction/MuonRecEvent/MuonSegment/MuonSegment/MuonSegment.h:45
Muon::MooTrackBuilder::m_pullCalculator
ToolHandle< Trk::IResidualPullCalculator > m_pullCalculator
Definition: MooTrackBuilder.h:275
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
AthAlgTool
Definition: AthAlgTool.h:26
Muon::CompareMuonSegmentKeys::SuperSet
@ SuperSet
Definition: CompareMuonSegmentKeys.h:19
Muon::MooTrackBuilder::combineWithSegmentFinding
std::vector< std::unique_ptr< Trk::Track > > combineWithSegmentFinding(const EventContext &ctx, const Trk::Track &track, const MuonSegment &seg, const PrepVec &patternPhiHits) const
find tracks by redoing the segment finding in the chamber of the segment
Definition: MooTrackBuilder.cxx:332
DataVector::erase
iterator erase(iterator position)
Remove element at a given position.
Muon::DistanceAlongParameters
Definition: SortMuPatHits.h:16
Muon::MooTrackBuilder::m_mdtRotCreator
ToolHandle< IMdtDriftCircleOnTrackCreator > m_mdtRotCreator
Definition: MooTrackBuilder.h:270
Muon::MooTrackBuilder::m_propagator
ToolHandle< Trk::IPropagator > m_propagator
Definition: MooTrackBuilder.h:274
Trk::Surface
Definition: Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/Surface.h:79
Muon::MMClusterOnTrack::detectorElement
virtual const MuonGM::MMReadoutElement * detectorElement() const
Returns the detector element, assoicated with the PRD of this class.
Definition: MMClusterOnTrack.h:139
Muon::IMuonSegmentTrackBuilder::PrepVec
std::vector< const Trk::PrepRawData * > PrepVec
Definition: IMuonSegmentTrackBuilder.h:26
Muon::MuPatTrack::segments
const std::vector< MuPatSegment * > & segments() const
access to segments
Definition: MuPatTrack.h:167
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
Muon::MooTrackBuilder::insertClustersWithCompetingRotCreation
Trk::TrackStates::const_iterator insertClustersWithCompetingRotCreation(const EventContext &ctx, Trk::TrackStates::const_iterator tsit, Trk::TrackStates::const_iterator tsit_end, std::vector< std::unique_ptr< const Trk::TrackStateOnSurface >> &states) const
Definition: MooTrackBuilder.cxx:722
Muon::MooTrackBuilder::removeDuplicateWithReference
void removeDuplicateWithReference(std::unique_ptr< Trk::SegmentCollection > &segments, std::vector< const MuonSegment * > &referenceSegments) const
Definition: MooTrackBuilder.cxx:482
CompareMuonSegmentKeys.h
Muon::MuPatCandidateBase::stations
const std::set< MuonStationIndex::StIndex > & stations() const
returns set with contained stationIndices
Definition: MuPatCandidateBase.cxx:29
calibdata.tube
tube
Definition: calibdata.py:30
zero
void zero(TH2 *h)
zero the contents of a 2d histogram
Definition: comparitor.cxx:438
DataVector::empty
bool empty() const noexcept
Returns true if the collection is empty.
Trk::TrackStateOnSurface::Measurement
@ Measurement
This is a measurement, and will at least contain a Trk::MeasurementBase.
Definition: TrackStateOnSurface.h:101
Muon::CompareMuonSegmentKeys
Definition: CompareMuonSegmentKeys.h:14
SegmentCollection.h
MuonSegmentKey.h
Muon::MuonClusterOnTrack
Base class for Muon cluster RIO_OnTracks.
Definition: MuonClusterOnTrack.h:34
Muon::MuonSegment::associatedSurface
virtual const Trk::PlaneSurface & associatedSurface() const override final
returns the surface for the local to global transformation
Definition: MuonSpectrometer/MuonReconstruction/MuonRecEvent/MuonSegment/MuonSegment/MuonSegment.h:175
DataVector::begin
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
NSWL1::PadTriggerAdapter::segment
Muon::NSW_PadTriggerSegment segment(const NSWL1::PadTrigger &data)
Definition: PadTriggerAdapter.cxx:5
tauRecTools::sortTracks
bool sortTracks(const ElementLink< xAOD::TauTrackContainer > &l1, const ElementLink< xAOD::TauTrackContainer > &l2)
Definition: Reconstruction/tauRecTools/Root/HelperFunctions.cxx:54
Identifier
Definition: IdentifierFieldParser.cxx:14