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 
203  bool slFit = !fieldCache.toroidOn() || nstations == 1 || (nstations == 2 && (stations.count(MuonStationIndex::EM) &&
204  (stations.count(MuonStationIndex::BO) || stations.count(MuonStationIndex::EO))));
205  if (msgLvl(MSG::DEBUG)) {
206  msg(MSG::DEBUG) << MSG::DEBUG << " combining entries: nstations " << nstations << " types:";
207  for (std::set<MuonStationIndex::StIndex>::iterator it = stations.begin(); it != stations.end(); ++it) {
209  }
210  if (slFit) {
211  msg(MSG::DEBUG) << " doing SL fit ";
212  } else {
213  msg(MSG::DEBUG) << " doing curved fit ";
214  }
215  msg(MSG::DEBUG) << endmsg;
216  }
217 
218  const MuPatTrack* trkCan1 = dynamic_cast<const MuPatTrack*>(&firstCandidate);
219  const MuPatTrack* trkCan2 = dynamic_cast<const MuPatTrack*>(&secondCandidate);
220 
221  const MuPatSegment* segCan1 = dynamic_cast<const MuPatSegment*>(&firstCandidate);
222  const MuPatSegment* segCan2 = dynamic_cast<const MuPatSegment*>(&secondCandidate);
223 
224  const MuPatTrack* candidate = nullptr;
225  const MuPatSegment* segment = nullptr;
226  if (trkCan1 && segCan2) {
227  candidate = trkCan1;
228  segment = segCan2;
229  } else if (trkCan2 && segCan1) {
230  candidate = trkCan2;
231  segment = segCan1;
232  }
233 
234  // check whether this combination was already tried, if yes reject the combination
235  if (candidate && segment) {
236  ATH_MSG_DEBUG(" Track/segment combination");
237  const std::vector<MuPatSegment*>& excl = candidate->excludedSegments();
238  if (std::find(excl.begin(),excl.end(), segment) != excl.end()){
239  ATH_MSG_DEBUG(" Rejected segment based on exclusion list");
240  return nullptr;
241  }
242  }
243 
244  // the following bit of code checks whether the current combination of segments was already tested
245  if (m_useTrackingHistory) {
246  // create a set of all segments of the would-be candidate
247  std::set<const MuPatSegment*> segments;
248  if ((segCan1 && segCan2)) {
249  segments.insert(segCan1);
250  segments.insert(segCan2);
251  }
252  if (candidate && segment) {
253  segments.insert(segment);
254  segments.insert(candidate->segments().begin(), candidate->segments().end());
255  }
256  // now loop over the segments and check if any of them is associated with a track that contains all of the segments
257 
258  for (const MuPatSegment* used : segments) {
259  // loop over the tracks associated with the current segment
260  for (const MuPatTrack* assoc_track : used->tracks()) {
261  // loop over the segments associated with the track
262  std::set<const MuPatSegment*> foundSegments;
263  for (const MuPatSegment* segOnTrack : assoc_track->segments()) {
264  if (segments.count(segOnTrack)) foundSegments.insert(segOnTrack);
265  }
266  // if all segments are already part of an existing track, don't perform the fit
267  if (foundSegments.size() == segments.size()) {
268  ATH_MSG_DEBUG("Combination already part of an existing track");
269  return nullptr;
270  }
271 
272  // if all segments but one are already part of an existing track, check the exclusion list
273  if (candidate && !candidate->excludedSegments().empty() && foundSegments.size() == segments.size() - 1) {
274  // create destination vector for segments that are not found
275  std::vector<const MuPatSegment*> unassociatedSegments(segments.size(), nullptr);
276  std::vector<const MuPatSegment*>::iterator it = std::set_difference(
277  segments.begin(), segments.end(), foundSegments.begin(), foundSegments.end(), unassociatedSegments.begin());
278  const MuPatSegment* zero = nullptr;
279  unassociatedSegments.erase(std::find(unassociatedSegments.begin(), unassociatedSegments.end(), zero),
280  unassociatedSegments.end());
281 
282  // check whether any pointers found
283  if (it != unassociatedSegments.begin()) {
284  // this should always be one as we required the difference to be one!
285  if (unassociatedSegments.size() != 1) {
286  ATH_MSG_DEBUG("Inconsistent result from set difference: size result "
287  << unassociatedSegments.size() << " candidate " << segments.size() << " found "
288  << foundSegments.size());
289  return nullptr;
290  }
291 
292  // check that the result is indeed part of the original set
293  if (!segments.count(unassociatedSegments.front())) {
294  ATH_MSG_DEBUG("Segment point not part of the original set, aborting!");
295  return nullptr;
296  }
297 
298  // now check whether the segment is part of the excluded segments
299  std::vector<MuPatSegment*>::const_iterator pos = std::find(
300  candidate->excludedSegments().begin(), candidate->excludedSegments().end(), unassociatedSegments.front());
301  if (pos != candidate->excludedSegments().end()) {
302  ATH_MSG_DEBUG("Segment found in exclusion list, not performing fit");
303  return nullptr;
304  }
305  }
306  }
307  }
308  }
309  }
310 
311  // use slFitter for straight line fit, or toroid off, otherwise use normal Fitter
312  if (slFit) return std::unique_ptr<Trk::Track>(m_slFitter->fit(ctx, firstCandidate, secondCandidate, externalPhiHits));
313 
314  return m_fitter->fit(ctx, firstCandidate, secondCandidate, externalPhiHits);
315  }
316 
317  std::unique_ptr<Trk::Track> MooTrackBuilder::combine(const EventContext& ctx, const Trk::Track& track, const MuonSegment& seg,
318  const PrepVec& externalPhiHits) const {
319 
320  // convert segments
321  std::unique_ptr<Trk::Track> inTrack = std::make_unique<Trk::Track>(track);
322  std::unique_ptr<MuPatTrack> candidate(m_candidateHandler->createCandidate(inTrack));
323  if (!candidate) return nullptr;
324  std::unique_ptr<MuPatSegment> segInfo(m_candidateHandler->createSegInfo(ctx, seg));
325  if (!segInfo) { return nullptr; }
326 
327  // call fit()
328  return combine(ctx, *candidate, *segInfo, externalPhiHits);
329  }
330 
331  std::vector<std::unique_ptr<Trk::Track> > MooTrackBuilder::combineWithSegmentFinding(const EventContext& ctx, const Trk::Track& track, const MuonSegment& seg,
332  const PrepVec& externalPhiHits) const {
333 
334  // convert segments
335  std::unique_ptr<Trk::Track> inTrack = std::make_unique<Trk::Track>(track);
336  std::unique_ptr<MuPatTrack> candidate = m_candidateHandler->createCandidate(inTrack);
337  if (!candidate) return {};
338  std::unique_ptr<MuPatSegment> segInfo(m_candidateHandler->createSegInfo(ctx, seg));
339  if (!segInfo) return {};
340  // call fit()
341  return combineWithSegmentFinding(ctx, *candidate, *segInfo, externalPhiHits);
342  }
343 
344  std::unique_ptr<Trk::TrackParameters> MooTrackBuilder::findClosestParameters(const Trk::Track& track, const Amg::Vector3D& pos) const {
345  // are we in the endcap?
346  bool isEndcap = m_edmHelperSvc->isEndcap(track);
347 
348  // position of segment
349  double posSeg = isEndcap ? pos.z() : pos.perp();
350 
351  // position closest parameters
352  double closest = 1e8;
353  const Trk::TrackParameters* closestParameters = nullptr;
354  bool closestIsMeasured = false;
355 
356  // loop over track and calculate residuals
357  const Trk::TrackStates* states = track.trackStateOnSurfaces();
358  if (!states) {
359  ATH_MSG_DEBUG(" track without states! ");
360  return nullptr;
361  }
362 
363  // loop over TSOSs
365  Trk::TrackStates::const_iterator tsit_end = states->end();
366  for (; tsit != tsit_end; ++tsit) {
367  // check whether state is a measurement
368  const Trk::MeasurementBase* meas = (*tsit)->measurementOnTrack();
369  if (!meas) { continue; }
370 
371  const Trk::TrackParameters* pars = (*tsit)->trackParameters();
372  if (!pars) { continue; }
373 
374  // check whether measured parameters
375  bool isMeasured = pars->covariance();
376 
377  // skip all none measured TrackParameters as soon as we found one with a measurement
378  if (closestIsMeasured && !isMeasured) continue;
379 
380  // calculate position parameters and compare with position segment
381  double posPars = isEndcap ? pars->position().z() : pars->position().perp();
382  double diffPos = std::abs(posPars - posSeg);
383 
384  // accept if measured parameters or the current accepted parameters are not yet measured
385  if ((isMeasured && !closestIsMeasured) || diffPos < closest) {
386  closest = diffPos;
387  closestParameters = pars;
388  closestIsMeasured = isMeasured;
389 
390  // if we are within 100 mm take current
391  if (closest < 100.) { break; }
392  }
393  }
394 
395  // return clone of parameters
396  if (closestParameters) return closestParameters->uniqueClone();
397  return nullptr;
398  }
399 
400  std::unique_ptr<Trk::TrackParameters> MooTrackBuilder::getClosestParameters(const MuPatCandidateBase& candidate, const Trk::Surface& surf) const {
401  // cast to segment, return segment parameters if cast success
402  const MuPatSegment* segCandidate = dynamic_cast<const MuPatSegment*>(&candidate);
403  if (segCandidate) return segCandidate->entryPars().uniqueClone();
404 
405  // for a track candidate, return the closest parameter on the track
406  const MuPatTrack& trkCandidate = dynamic_cast<const MuPatTrack&>(candidate);
407  return getClosestParameters(trkCandidate.track(), surf);
408  }
409 
410  std::unique_ptr<Trk::TrackParameters> MooTrackBuilder::getClosestParameters(const Trk::Track& track, const Trk::Surface& surf) const {
412  }
413 
414  std::vector<std::unique_ptr<Trk::Track> > MooTrackBuilder::combineWithSegmentFinding(const EventContext& ctx, const Trk::Track& track,
415  const Trk::TrackParameters& pars,
416  const std::set<Identifier>& chIds,
417  const PrepVec& patternPhiHits) const {
418  // convert track
419  std::unique_ptr<Trk::Track> inTrack = std::make_unique<Trk::Track>(track);
420  std::unique_ptr<MuPatTrack> can = m_candidateHandler->createCandidate(inTrack);
421  if (!can) { return {}; }
422  return combineWithSegmentFinding(ctx, *can, pars, chIds, patternPhiHits);
423  }
424 
425  std::vector<std::unique_ptr<Trk::Track> > MooTrackBuilder::combineWithSegmentFinding(const EventContext& ctx, const MuPatTrack& candidate,
426  const MuPatSegment& segInfo,
427  const PrepVec& externalPhiHits) const {
434  const MuonSegment& seg = *segInfo.segment;
435  std::vector<std::unique_ptr<Trk::Track> > newTracks;
436 
437  // get chamber Id of segment
438  std::set<Identifier> chIds = m_edmHelperSvc->chamberIds(seg);
439 
440  if (chIds.empty()) return newTracks;
441 
442  // for now do not redo segment making for CSCs
443  if (m_idHelperSvc->isCsc(*chIds.begin())) {
444  if (m_candidateMatchingTool->match(ctx, candidate, segInfo, true)) {
445  std::unique_ptr<Trk::Track> newtrack(m_fitter->fit(ctx, candidate, segInfo, externalPhiHits));
446  if (newtrack) newTracks.push_back(std::move(newtrack));
447  return newTracks;
448  } else {
449  return newTracks;
450  }
451  }
452 
453  const Trk::Track& track = candidate.track();
454  ATH_MSG_DEBUG(" in combineWithSegmentFinding ");
455  ATH_MSG_VERBOSE(" segment " << m_printer->print(seg));
456 
457  // find track parameters on segment surface
458  std::unique_ptr<Trk::TrackParameters> closestPars(findClosestParameters(track, seg.globalPosition()));
459 
460  if (!closestPars) {
461  ATH_MSG_WARNING(" unable to find closest TrackParameters ");
462  return newTracks;
463  }
464 
465  ATH_MSG_VERBOSE(" closest parameter " << m_printer->print(*closestPars));
466 
467  // propagate to segment surface
468  std::unique_ptr<Trk::TrackParameters> exPars(
469  m_propagator->propagate(ctx,*closestPars, seg.associatedSurface(), Trk::anyDirection, false, m_magFieldProperties));
470 
471  if (!exPars) {
472  ATH_MSG_WARNING(" Propagation failed!! ");
473  return newTracks;
474  }
475 
476  ATH_MSG_VERBOSE(" extrapolated parameter " << m_printer->print(*exPars));
477 
478  return combineWithSegmentFinding(ctx, candidate, *exPars, chIds, externalPhiHits);
479  }
480 
481  void MooTrackBuilder::removeDuplicateWithReference(std::unique_ptr<Trk::SegmentCollection>& segments,
482  std::vector<const MuonSegment*>& referenceSegments) const {
483  if (referenceSegments.empty()) return;
484 
485  ATH_MSG_DEBUG(" Removing duplicates from segment vector of size " << segments->size() << " reference size "
486  << referenceSegments.size());
487 
488  CompareMuonSegmentKeys compareSegmentKeys{};
489 
490  // create a vector with pairs of MuonSegmentKey and a pointer to the corresponding segment to resolve ambiguities
491  std::vector<std::pair<MuonSegmentKey, Trk::SegmentCollection::iterator> > segKeys;
492  segKeys.reserve(segments->size());
493 
494  // loop over reference segments and make keys
495  Trk::SegmentCollection::iterator sit = segments->begin();
496  Trk::SegmentCollection::iterator sit_end = segments->end();
497  for (; sit != sit_end; ++sit) {
498  Trk::Segment* tseg = *sit;
499  MuonSegment* mseg = dynamic_cast<MuonSegment*>(tseg);
500  segKeys.emplace_back(MuonSegmentKey(*mseg), sit);
501  }
502 
503  // create a vector with pairs of MuonSegmentKey and a pointer to the corresponding segment to resolve ambiguities
504  std::vector<MuonSegmentKey> referenceSegKeys;
505  referenceSegKeys.reserve(referenceSegments.size());
506 
507  // loop over reference segments and make keys
508  std::vector<const MuonSegment*>::iterator vit = referenceSegments.begin();
509  std::vector<const MuonSegment*>::iterator vit_end = referenceSegments.end();
510  for (; vit != vit_end; ++vit) { referenceSegKeys.emplace_back(**vit); }
511 
512  // loop over segments and compare the current segment with the reference ones
513  std::vector<std::pair<MuonSegmentKey, Trk::SegmentCollection::iterator> >::iterator skit = segKeys.begin();
514  std::vector<std::pair<MuonSegmentKey, Trk::SegmentCollection::iterator> >::iterator skit_end = segKeys.end();
515  for (; skit != skit_end; ++skit) {
516  bool isDuplicate = false;
517 
518  std::vector<MuonSegmentKey>::iterator rskit = referenceSegKeys.begin();
519  std::vector<MuonSegmentKey>::iterator rskit_end = referenceSegKeys.end();
520 
521  for (; rskit != rskit_end; ++rskit) {
522  CompareMuonSegmentKeys::OverlapResult overlapResult = compareSegmentKeys(*rskit, skit->first);
523  if (overlapResult == CompareMuonSegmentKeys::Identical) {
524  ATH_MSG_DEBUG(" discarding identical segment");
525  isDuplicate = true;
526  break;
527  } else if (overlapResult == CompareMuonSegmentKeys::SuperSet) {
528  // reference segment superset of current: discard
529  ATH_MSG_DEBUG(" discarding (subset) ");
530  isDuplicate = true;
531  break;
532  }
533  }
534  if (isDuplicate) segments->erase(skit->second);
535  }
536  }
537 
538  std::vector<std::unique_ptr<Trk::Track> > MooTrackBuilder::combineWithSegmentFinding(const EventContext& ctx, const MuPatTrack& candidate,
539  const Trk::TrackParameters& pars,
540  const std::set<Identifier>& chIds,
541  const PrepVec& externalPhiHits) const {
542  std::vector<std::unique_ptr<Trk::Track> > newTracks;
543 
544  if (chIds.empty()) return newTracks;
545 
546  if (!m_idHelperSvc->isMdt(*chIds.begin())) {
547  ATH_MSG_WARNING("combineWithSegmentFinding called with CSC hits!! retuning zero pointer");
548  return newTracks;
549  }
550 
551  // redo segment finding
552  std::unique_ptr<Trk::SegmentCollection> segments = m_seededSegmentFinder->find(ctx, pars, chIds);
553 
554  // check whether we got segments
555  if (!segments) {
556  ATH_MSG_DEBUG(" failed to find new segments ");
557  return newTracks;
558  }
559  if (segments->empty()) {
560  ATH_MSG_DEBUG(" got empty vector!! ");
561  return newTracks;
562  }
563 
564  unsigned int nseg = segments->size();
565  if (m_useExclusionList) {
566  std::vector<const MuonSegment*> referenceSegments;
567  for (std::vector<MuPatSegment*>::const_iterator esit = candidate.excludedSegments().begin();
568  esit != candidate.excludedSegments().end(); ++esit) {
569  if ((*esit)->segment) referenceSegments.push_back((*esit)->segment);
570  }
571  removeDuplicateWithReference(segments, referenceSegments);
572  }
573 
574  if (msgLvl(MSG::DEBUG) && segments->size() != nseg) {
576  << " Rejected segments based on exclusion list, number of removed segments: " << nseg - segments->size()
577  << " total " << segments->size() << endmsg;
578  }
579 
580  if (!segments->empty()) {
581  // loop over segments
582  for (Trk::Segment* tseg : *segments) {
583  if (!tseg) continue;
584  MuonSegment* mseg = dynamic_cast<MuonSegment*>(tseg);
585 
586  if (msgLvl(MSG::DEBUG)) {
587  msg(MSG::DEBUG) << MSG::DEBUG << " adding segment " << m_printer->print(*mseg);
588  if (msgLvl(MSG::VERBOSE)) {
589  msg(MSG::DEBUG) << std::endl << m_printer->print(mseg->containedMeasurements()) << endmsg;
590  if (msgLvl(MSG::VERBOSE) && candidate.track().measurementsOnTrack())
591  msg(MSG::DEBUG) << " track " << m_printer->print(candidate.track()) << std::endl
592  << m_printer->print(candidate.track().measurementsOnTrack()->stdcont()) << endmsg;
593  } else {
594  msg(MSG::DEBUG) << endmsg;
595  }
596  }
597  std::unique_ptr<MuPatSegment> segInfo{m_candidateHandler->createSegInfo(ctx, *mseg)};
598 
599  if (!m_candidateMatchingTool->match(ctx, candidate, *segInfo, true)) { continue; }
600 
601  std::unique_ptr<Trk::Track> segTrack = m_fitter->fit(ctx, candidate, *segInfo, externalPhiHits);
602 
603  if (!segTrack) continue;
604 
605  ATH_MSG_DEBUG(" found new track " << m_printer->print(*segTrack));
606  newTracks.push_back(std::move(segTrack));
607  }
608  }
609 
610  if (!newTracks.empty()) ATH_MSG_DEBUG(" found new tracks for segment " << newTracks.size());
611 
612  return newTracks;
613  }
614 
615  std::unique_ptr<Trk::Track> MooTrackBuilder::recalibrateHitsOnTrack(const EventContext& ctx, const Trk::Track& track, bool doMdts,
616  bool doCompetingClusters) const {
617  // loop over track and calculate residuals
618  const Trk::TrackStates* states = track.trackStateOnSurfaces();
619  if (!states) {
620  ATH_MSG_DEBUG(" track without states, discarding track ");
621  return nullptr;
622  }
623  if (msgLvl(MSG::DEBUG)) {
624  msg(MSG::DEBUG) << MSG::DEBUG << " recalibrating hits on track " << std::endl << m_printer->print(track);
625 
626  if (msgLvl(MSG::VERBOSE)) {
627  if (track.measurementsOnTrack())
628  msg(MSG::DEBUG) << std::endl << m_printer->print(track.measurementsOnTrack()->stdcont()) << endmsg;
629  } else {
630  msg(MSG::DEBUG) << endmsg;
631  }
632  }
633  // vector to store states, the boolean indicated whether the state was create in this routine (true) or belongs to the track (false)
634  // If any new state is created, all states will be cloned and a new track will beformed from them.
635  std::vector<std::unique_ptr<const Trk::TrackStateOnSurface>> newStates;
636  newStates.reserve(states->size() + 5);
637 
638  // loop over TSOSs
639  Trk::TrackStates::const_iterator state_itr = states->begin();
640  Trk::TrackStates::const_iterator end_itr = states->end();
641  for (; state_itr != end_itr; ++state_itr) {
642  const Trk::TrackStateOnSurface* tsit = (*state_itr);
643  if (!tsit) continue; // sanity check
644 
645  // check whether state is a measurement
646  const Trk::TrackParameters* pars = tsit->trackParameters();
647  if (!pars) {
648  newStates.emplace_back(tsit->clone());
649  continue;
650  }
651 
652  // check whether state is a measurement
653  const Trk::MeasurementBase* meas = tsit->measurementOnTrack();
654  if (!meas) {
655  newStates.emplace_back(tsit->clone());
656  continue;
657  }
658 
659  Identifier id = m_edmHelperSvc->getIdentifier(*meas);
660 
661  // Not a ROT, else it would have had an identifier. Keep the TSOS.
662  if (!id.is_valid() || !m_idHelperSvc->isMuon(id)) {
663  newStates.emplace_back(tsit->clone());
664  continue;
665  }
666 
667  ATH_MSG_VERBOSE(" new measurement " << m_idHelperSvc->toString(id));
668 
669  if (m_idHelperSvc->isMdt(id)) {
670  if (doMdts) {
671  const MdtDriftCircleOnTrack* mdt = dynamic_cast<const MdtDriftCircleOnTrack*>(meas);
672  if (!mdt) {
673  ATH_MSG_WARNING(" Measurement with MDT identifier that is not a MdtDriftCircleOnTrack ");
674  continue;
675  }
676  std::unique_ptr<Trk::RIO_OnTrack> newMdt(m_mdtRotCreator->correct(*mdt->prepRawData(), *pars));
677  if (!newMdt) {
678  ATH_MSG_WARNING(" Failed to recalibrate MDT ");
679  continue;
680  }
681  std::unique_ptr<Trk::TrackStateOnSurface> tsos = MuonTSOSHelper::createMeasTSOSWithUpdate(
682  *tsit, std::move(newMdt), pars->uniqueClone(),
685  newStates.push_back(std::move(tsos));
686 
687  } else {
688  newStates.emplace_back(tsit->clone());
689  }
690 
691  } else if (m_idHelperSvc->isCsc(id)) {
692  newStates.emplace_back(tsit->clone());
693 
694  } else if (m_idHelperSvc->isTrigger(id)) {
695  if (doCompetingClusters) {
696  state_itr = insertClustersWithCompetingRotCreation(ctx, state_itr, end_itr, newStates);
697  } else {
698  newStates.emplace_back(tsit->clone());
699  }
700 
701  } else if (m_idHelperSvc->isMM(id) || m_idHelperSvc->issTgc(id)) {
702  newStates.emplace_back(tsit->clone());
703  } else {
704  ATH_MSG_WARNING(" unknown Identifier ");
705  }
706  }
707 
708  ATH_MSG_DEBUG(" original track had " << states->size() << " TSOS, adding " << newStates.size() - states->size() << " new TSOS ");
709 
710  // states were added, create a new track
711  auto trackStateOnSurfaces = std::make_unique<Trk::TrackStates>();
712  trackStateOnSurfaces->reserve(newStates.size());
713  for (std::unique_ptr<const Trk::TrackStateOnSurface>& new_state : newStates) {
714  // 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
715  trackStateOnSurfaces->push_back(std::move(new_state));
716  }
717  return std::make_unique<Trk::Track>(track.info(), std::move(trackStateOnSurfaces),
718  track.fitQuality() ? track.fitQuality()->uniqueClone() : nullptr);
719  }
720 
724  std::vector<std::unique_ptr<const Trk::TrackStateOnSurface> >& states) const {
725  // iterator should point to a valid element
726  if (tsit == tsit_end) {
727  ATH_MSG_WARNING(" iterator pointing to end of vector, this should no happen ");
728  return --tsit;
729  }
730 
731  // check whether state is a measurement
732  const Trk::MeasurementBase* meas = (*tsit)->measurementOnTrack();
733  const Trk::TrackParameters* pars = (*tsit)->trackParameters();
734  if (!meas || !pars) {
735  ATH_MSG_WARNING(" iterator pointing to a TSOS without a measurement or TrackParameters ");
736  if (tsit + 1 == tsit_end) --tsit;
737  return tsit;
738  }
739 
740  ATH_MSG_VERBOSE(" inserting with competing ROT creation ");
741 
742  // loop over states until we reached the last tgc hit in this detector element
743  // keep trackof the identifiers and the states
744  std::list<const Trk::PrepRawData*> etaPrds;
745  std::list<const Trk::PrepRawData*> phiPrds;
746  const Trk::TrkDetElementBase* currentDetEl = nullptr;
747  std::vector<std::unique_ptr<const Trk::TrackStateOnSurface> > newStates;
748  // keep track of outliers as we might have to drop them..
749  std::vector<std::pair<bool, const Trk::TrackStateOnSurface*> > outlierStates;
750  bool hasPhi {false}, hasEta{false};
751 
752  for (; tsit != tsit_end; ++tsit) {
753  const Trk::TrackStateOnSurface* in_tsos = *tsit;
754  if (!in_tsos) continue;
755 
756  // check whether state is a measurement, keep if not
757  const Trk::MeasurementBase* meas = in_tsos->measurementOnTrack();
758  if (!meas) {
759  newStates.emplace_back(in_tsos->clone());
760  continue;
761  }
762 
763  // get identifier, keep state if it has no identifier.
764  Identifier id = m_edmHelperSvc->getIdentifier(*meas);
765  if (!id.is_valid()) {
766  newStates.emplace_back(in_tsos->clone());
767  continue;
768  }
769 
770  // sanity check, this SHOULD be a RPC, TGC or CSC measurement
771  if (!(m_idHelperSvc->isTrigger(id))) { break; }
772 
773  bool measuresPhi = m_idHelperSvc->measuresPhi(id);
774  if (!hasPhi && measuresPhi) hasPhi = true;
775  if (!hasEta && !measuresPhi) hasEta = true;
776 
777  // check whether state is a measurement
778  if ((*tsit)->type(Trk::TrackStateOnSurface::Outlier)) {
779  outlierStates.emplace_back(measuresPhi, in_tsos);
780  continue;
781  }
782 
783  // check whether we are still in the same chamber, stop loop if not
784 
785  ATH_MSG_VERBOSE(" handling " << m_idHelperSvc->toString(id));
786 
787  std::list<const Trk::PrepRawData*>& prdList = measuresPhi ? phiPrds : etaPrds;
788  const MuonClusterOnTrack* clus = dynamic_cast<const MuonClusterOnTrack*>(meas);
789  if (clus) {
790  const Trk::TrkDetElementBase* detEl = clus->detectorElement();
791  if (!currentDetEl) currentDetEl = detEl;
792  if (detEl != currentDetEl) {
793  ATH_MSG_VERBOSE(" new detector element stopping ");
794  break;
795  }
796  prdList.push_back(clus->prepRawData());
797  } else {
798  // split competing ROTs into constituents
799  const CompetingMuonClustersOnTrack* comp = dynamic_cast<const CompetingMuonClustersOnTrack*>(meas);
800  if (comp) {
801  const Trk::TrkDetElementBase* detEl = nullptr;
802  if (comp->containedROTs().empty()) {
803  ATH_MSG_WARNING(" CompetingROT without constituents ");
804  break;
805  }
806  detEl = comp->containedROTs().front()->detectorElement();
807  if (!currentDetEl) currentDetEl = detEl;
808  if (detEl != currentDetEl) {
809  ATH_MSG_VERBOSE(" new detector element stopping ");
810  break;
811  }
812  std::vector<const MuonClusterOnTrack*>::const_iterator clit = comp->containedROTs().begin();
813  std::vector<const MuonClusterOnTrack*>::const_iterator clit_end = comp->containedROTs().end();
814  for (; clit != clit_end; ++clit) { prdList.push_back((*clit)->prepRawData()); }
815 
816  } else {
817  ATH_MSG_WARNING(" Unknown trigger hit type! ");
818  continue;
819  }
820  }
821  }
822 
823  // now that we have the lists of prds we can create the competing rots
824  if (!etaPrds.empty()) {
825  std::unique_ptr<CompetingMuonClustersOnTrack> etaCompRot = m_compRotCreator->createBroadCluster(etaPrds, 0.);
826  if (!etaCompRot) {
827  ATH_MSG_WARNING(" Failed to create CompetingMuonClustersOnTrack for eta hits! ");
828  } else {
829  std::unique_ptr<Trk::TrackParameters> etaPars;;
830  // check whether original parameters are on surface, if so clone original parameters
831  if (etaCompRot->associatedSurface() == pars->associatedSurface()) {
832  etaPars = pars->uniqueClone();
833  } else {
834  // ownership relinquished, should be treated in createMeasTSOS
835  etaPars =
836  m_propagator->propagate(ctx,*pars,
837  etaCompRot->associatedSurface(),
839  }
840  if (!etaPars) {
841  ATH_MSG_WARNING(" Failed to calculate TrackParameters for eta hits! ");
842  } else {
843  std::unique_ptr<Trk::TrackStateOnSurface> tsos =
844  MuonTSOSHelper::createMeasTSOS(std::move(etaCompRot), std::move(etaPars), Trk::TrackStateOnSurface::Measurement);
845  newStates.push_back(std::move(tsos));
846  }
847  }
848  }
849 
850  if (!phiPrds.empty()) {
851  std::unique_ptr<CompetingMuonClustersOnTrack> phiCompRot = m_compRotCreator->createBroadCluster(phiPrds, 0.);
852  if (!phiCompRot) {
853  ATH_MSG_WARNING(" Failed to create CompetingMuonClustersOnTrack for phi hits! ");
854  } else {
855  std::unique_ptr<Trk::TrackParameters> phiPars;
856  // check whether original parameters are on surface, if so clone original parameters
857  if (phiCompRot->associatedSurface() == pars->associatedSurface()) {
858  phiPars = pars->uniqueClone();
859  } else {
860  // ownership relinquished, handled in createMeasTSOS
861  phiPars =
862  m_propagator->propagate(ctx, *pars, phiCompRot->associatedSurface(),
864  }
865  if (!phiPars) {
866  ATH_MSG_WARNING(" Failed to calculate TrackParameters for phi hits! ");
867  } else {
868  std::unique_ptr<Trk::TrackStateOnSurface> tsos =
869  MuonTSOSHelper::createMeasTSOS(std::move(phiCompRot), std::move(phiPars), Trk::TrackStateOnSurface::Measurement);
870  newStates.push_back(std::move(tsos));
871  }
872  }
873  }
874 
875  // add outliers if there was no measurement on track in the same projection
876  for (const auto& outlier : outlierStates) {
877  if (hasPhi && outlier.first)
878  newStates.emplace_back(outlier.second->clone());
879  else if (hasEta && !outlier.first)
880  newStates.emplace_back(outlier.second->clone());
881  else if (msgLvl(MSG::DEBUG))
882  msg(MSG::DEBUG) << " Dropping outlier " << endmsg;
883  }
884 
885  // sort all states in this chamber
886  std::stable_sort(newStates.begin(), newStates.end(), SortTSOSByDistanceToPars(pars));
887 
888  // insert the states into
889  states.insert(states.end(), std::make_move_iterator(newStates.begin()),
890  std::make_move_iterator(newStates.end()));
891 
892  // iterator should point to the last TGC in this chamber
893  return --tsit;
894  }
895 
896  std::pair<std::unique_ptr<Trk::Track>, std::unique_ptr<Trk::Track> > MooTrackBuilder::splitTrack(const EventContext& ctx, const Trk::Track& track) const {
897  // use slFitter for straight line fit, or toroid off, otherwise use normal Fitter
898 
899  if (m_edmHelperSvc->isSLTrack(track)) return m_slFitter->splitTrack(ctx, track);
900 
901  MagField::AtlasFieldCache fieldCache;
902  // Get field cache object
904  const AtlasFieldCacheCondObj* fieldCondObj{*readHandle};
905 
906  if (!fieldCondObj) {
907  ATH_MSG_ERROR("splitTrack: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCacheCondObjInputKey.key());
908  return {};
909  }
910  fieldCondObj->getInitializedCache(fieldCache);
911 
912  if (!fieldCache.toroidOn()) return m_slFitter->splitTrack(ctx, track);
913 
914  return m_fitter->splitTrack(ctx, track);
915  }
916 
917  std::vector<std::unique_ptr<MuPatTrack> > MooTrackBuilder::find(const EventContext& ctx, MuPatCandidateBase& candidate,
918  const std::vector<MuPatSegment*>& segVec) const {
919  std::vector<std::unique_ptr<MuPatTrack> > candidates;
920  // check whether we have segments
921  if (segVec.empty()) return candidates;
922 
923  std::set<MuPatSegment*> usedSegments;
924  std::map<MuPatSegment*, MuPatSegment*> slSegments;
925 
926  // int looseQualityLevel = 1; // Not used for the moment
927  bool tightQualityCuts = false;
928  ATH_MSG_DEBUG(" find: " << m_candidateHandler->print(candidate, 0) << std::endl << m_candidateHandler->print(segVec, 0));
929 
930  // store whether segment was added to at least one candidates
931 
932  // vector to store candidate extensions
933  std::vector<std::pair<MuPatSegment*, std::unique_ptr<Trk::Track> > > extensions;
934  extensions.reserve(segVec.size());
935 
936  // loop over segments
937  for (MuPatSegment* seg : segVec) {
938  if (usedSegments.count(seg)) continue;
939 
940  // check whether chamber is already included in candidate
941  if (candidate.shareChambers(*seg)) {
942  ATH_MSG_VERBOSE("addStationToSeed:: already on candidate " << std::endl << m_printer->print(*seg->segment));
943  continue;
944  }
945 
946  if (!m_candidateMatchingTool->match(ctx, candidate, *seg, tightQualityCuts)) {
947  ATH_MSG_VERBOSE(" track/segment combination rejected based on angular matching " << std::endl
948  << m_printer->print(*seg->segment));
949  continue;
950  }
951 
952  ATH_MSG_VERBOSE("combining: " << m_printer->print(*seg->segment));
953 
954  // try to combine track with segment
955  std::unique_ptr<Trk::Track> track = combine(ctx, candidate, *seg, emptyPhiHits);
956 
957  // additional check in case the candidate is a MuPatTrack
958  MuPatTrack* trkCan = dynamic_cast<MuPatTrack*>(&candidate);
959  MuPatSegment* segCan = dynamic_cast<MuPatSegment*>(&candidate);
960  if (trkCan) {
961  if (!track) {
962  trkCan->addExcludedSegment(seg);
963  continue;
964  }
965 
966  // is the new track better
968  if (!sortTracks(*track, trkCan->track())) {
969  ATH_MSG_VERBOSE(" rejecting track as new segment results in worse fit");
970  continue;
971  }
972 
973  // check whether the track cleaner didn't remove one of the already added chamber layers
974  // loop over hits
975  std::set<MuonStationIndex::StIndex> stationLayersOnTrack;
976  for ( const Trk::MeasurementBase* meas : *track->measurementsOnTrack()) {
977  Identifier id = m_edmHelperSvc->getIdentifier(*meas);
978  if (!id.is_valid() || m_idHelperSvc->isTrigger(id)) { continue; }
979  stationLayersOnTrack.insert(m_idHelperSvc->stationIndex(id));
980  }
981 
982  bool hasAllLayers = true;
983  for (const MuonStationIndex::StIndex& stIdx :candidate.stations()) {
984  if (!stationLayersOnTrack.count(stIdx)) {
985  ATH_MSG_VERBOSE(" missing layer " << MuonStationIndex::stName(stIdx));
986  hasAllLayers = false;
987  }
988  }
989 
990  if (!hasAllLayers) {
991  ATH_MSG_VERBOSE(" rejecting track as one of the chamber layers of the candidate was removed ");
992  continue;
993  }
994  }
995 
996  if (!track) { continue; }
997 
998  usedSegments.insert(seg);
999 
1000  // now loop over segments once more and try to add SL overlap if missed
1001  // first check that segment is not an overlap segment
1002  if (!seg->hasSLOverlap()) {
1003  std::unique_ptr<MuPatTrack> newCandidate;
1004  // loop over segments
1005  for (MuPatSegment* seg_1 : segVec) {
1006  // select segments is different chamber
1007  if (seg->chIndex == seg_1->chIndex) continue;
1008 
1009  if (!newCandidate) {
1010  std::unique_ptr<Trk::Track> trkTrkCan = std::make_unique<Trk::Track>(*track);
1011  if (trkCan) {
1012  // copy candidate and add segment
1013  newCandidate = std::make_unique<MuPatTrack>(*trkCan);
1014  m_candidateHandler->extendWithSegment(*newCandidate, *seg, trkTrkCan);
1015  } else if (segCan) {
1016  newCandidate = m_candidateHandler->createCandidate(*segCan, *seg, trkTrkCan);
1017  }
1018  if (!newCandidate) break;
1019  }
1020  if (!m_candidateMatchingTool->match(ctx, *newCandidate, *seg_1, tightQualityCuts)) {
1021  ATH_MSG_VERBOSE("track/segment combination rejected based on angular matching "
1022  << std::endl
1023  << m_printer->print(*seg->segment));
1024  continue;
1025  }
1026 
1027  ATH_MSG_VERBOSE("adding SL overlap " << m_printer->print(*seg_1->segment));
1028  std::unique_ptr<Trk::Track> slOverlapTrack = combine(ctx, *track, *seg_1->segment, emptyPhiHits);
1029  if (!slOverlapTrack) continue;
1030 
1031  // is the new track better
1033  if (!sortTracks(*slOverlapTrack, *track)) {
1034  ATH_MSG_VERBOSE(__FILE__<<":"<<__LINE__<<" rejecting track as new segment results in worse fit");
1035  continue;
1036  }
1037  ATH_MSG_VERBOSE("adding SL overlap ok, new track" << m_printer->print(*slOverlapTrack) << std::endl
1038  << m_printer->printStations(*slOverlapTrack));
1039 
1040  track.swap(slOverlapTrack);
1041  usedSegments.insert(seg_1);
1042  slSegments[seg] = seg_1;
1043  break;
1044  }
1045  }
1046 
1047  ATH_MSG_VERBOSE(" Track found " << m_printer->print(*track)<<std::endl<<m_printer->printMeasurements(*track));
1048 
1049  // add new solution
1050  extensions.emplace_back(seg, std::move(track));
1051 
1052  } // for (sit)
1053 
1054  // loop over solutions and add them
1055  if (!extensions.empty()) {
1056  candidates.reserve(extensions.size());
1057 
1058  // additional check in case the candidate is a MuPatTrack
1059  MuPatTrack* trkCan = dynamic_cast<MuPatTrack*>(&candidate);
1060  MuPatSegment* segCan = dynamic_cast<MuPatSegment*>(&candidate);
1061 
1062  // if more than 1 extensions are found, first add the copies
1063  // start from the second one to make copies based on the existing candidates
1064  for (std::pair<MuPatSegment*, std::unique_ptr<Trk::Track> >& ext_itr : extensions) {
1065  std::unique_ptr<MuPatTrack> newCandidate;
1066  if (trkCan) {
1067  // copy candidate and add segment
1068  newCandidate = std::make_unique<MuPatTrack>(*trkCan);
1069  m_candidateHandler->extendWithSegment(*newCandidate, *ext_itr.first, ext_itr.second);
1070  } else if (segCan) {
1071  newCandidate = m_candidateHandler->createCandidate(*segCan, *ext_itr.first, ext_itr.second);
1072  }
1073  ATH_MSG_DEBUG(" " << m_printer->print(*ext_itr.first->segment));
1074  MuPatSegment* slOverlap = slSegments[ext_itr.first];
1075 
1076  if (slOverlap) {
1077  ATH_MSG_DEBUG("SLOverlap " << m_printer->print(*slOverlap->segment));
1078  // hack to allow me to add a second segment without changing the track
1079  std::unique_ptr<Trk::Track> nullTrack;
1080  newCandidate->addSegment(slOverlap, nullTrack);
1081  }
1082  candidates.push_back(std::move(newCandidate));
1083 
1084  ATH_MSG_DEBUG(" creating new candidate " << candidates.back().get() << std::endl
1085  << m_printer->print(candidates.back()->track()) << std::endl
1086  << m_printer->printStations(candidates.back()->track()));
1087  }
1088  }
1089  return candidates;
1090  }
1091 
1092  bool MooTrackBuilder::isSplitTrack(const EventContext& ctx, const Trk::Track& track1, const Trk::Track& track2) const {
1093  // some loose association cuts
1094  const DataVector<const Trk::TrackParameters>* parsVec1 = track1.trackParameters();
1095  if (!parsVec1 || parsVec1->empty()) {
1096  ATH_MSG_WARNING(" isSplitTrack::Track without parameters! ");
1097  return false;
1098  }
1099  const Trk::TrackParameters* pars1 = parsVec1->front();
1100  if (!pars1) {
1101  ATH_MSG_WARNING(" isSplitTrack::Track without NULL pointer in parameter vector! ");
1102  return false;
1103  }
1104 
1105  const DataVector<const Trk::TrackParameters>* parsVec2 = track2.trackParameters();
1106  if (!parsVec2 || parsVec2->empty()) {
1107  ATH_MSG_WARNING(" isSplitTrack::Track without parameters! ");
1108  return false;
1109  }
1110  const Trk::TrackParameters* pars2 = parsVec2->front();
1111  if (!pars2) {
1112  ATH_MSG_WARNING(" isSplitTrack::Track without NULL pointer in parameter vector! ");
1113  return false;
1114  }
1115 
1116  if (!m_candidateMatchingTool->sameSide(pars1->momentum().unit(), pars1->position(), pars2->position(), true)) {
1117  ATH_MSG_DEBUG(" tracks in opposite hemispheres ");
1118  return false;
1119  }
1120 
1121  double sinTheta1 = sin(pars1->momentum().theta());
1122  double sinTheta2 = sin(pars2->momentum().theta());
1123  double deltaSinTheta = sinTheta1 - sinTheta2;
1124  if (std::abs(deltaSinTheta) > 1.) {
1125  ATH_MSG_DEBUG(" too large opening angle in theta " << deltaSinTheta);
1126  // return false;
1127  }
1128  double sinPhi1 = sin(pars1->momentum().phi());
1129  double sinPhi2 = sin(pars2->momentum().phi());
1130  double deltaSinPhi = sinPhi1 - sinPhi2;
1131  if (std::abs(deltaSinPhi) > 1.) {
1132  ATH_MSG_DEBUG(" too large opening angle in phi " << deltaSinPhi);
1133  // return false;
1134  }
1135 
1136  const Trk::Track* referenceTrack = nullptr;
1137  const Trk::Track* otherTrack = nullptr;
1138 
1139  // first check whether the tracks have a momentum measurement
1140  bool isSL1 = m_edmHelperSvc->isSLTrack(track1);
1141  bool isSL2 = m_edmHelperSvc->isSLTrack(track2);
1142 
1143  // now decide which track to use as reference
1144  if (isSL1 && !isSL2) {
1145  referenceTrack = &track2;
1146  otherTrack = &track1;
1147  } else if (!isSL1 && isSL2) {
1148  referenceTrack = &track1;
1149  otherTrack = &track2;
1150  } else {
1152  bool pickFirst = sortTracks(track1, track2);
1153  if (pickFirst) {
1154  referenceTrack = &track1;
1155  otherTrack = &track2;
1156  } else {
1157  referenceTrack = &track2;
1158  otherTrack = &track1;
1159  }
1160  }
1161 
1162  ATH_MSG_DEBUG(" close tracks " << std::endl << m_printer->print(*referenceTrack) << std::endl << m_printer->print(*otherTrack));
1163 
1164  // get iterators to TSOSs
1165  const Trk::TrackStates* statesRef = referenceTrack->trackStateOnSurfaces();
1166  if (!statesRef) {
1167  ATH_MSG_WARNING(" track without states, cannot perform cleaning ");
1168  return false;
1169  }
1170  Trk::TrackStates::const_iterator refTSOS = statesRef->begin();
1171  Trk::TrackStates::const_iterator refTSOS_end = statesRef->end();
1172 
1173  const Trk::TrackStates* statesOther = otherTrack->trackStateOnSurfaces();
1174  if (!statesOther) {
1175  ATH_MSG_WARNING(" track without states, cannot perform cleaning ");
1176  return false;
1177  }
1178  Trk::TrackStates::const_iterator otherTSOS = statesOther->begin();
1179  Trk::TrackStates::const_iterator otherTSOS_end = statesOther->end();
1180 
1181  DistanceAlongParameters distAlongPars;
1182 
1183  unsigned int nmatching(0);
1184  unsigned int noff(0);
1185 
1186  // keep track of previous distance and parameters as well
1187  double prevDist = 1e10;
1188  const Trk::TrackParameters* prevPars = nullptr;
1189 
1190  // now loop over the TSOSs of both tracks and compare hit by hit
1191  while (refTSOS != refTSOS_end && otherTSOS != otherTSOS_end) {
1192  const Trk::TrackParameters* parsRef = (*refTSOS)->trackParameters();
1193  if (!parsRef) {
1194  ++refTSOS;
1195  continue;
1196  }
1197 
1198  const Trk::TrackParameters* parsOther = (*otherTSOS)->trackParameters();
1199  if (!parsOther) {
1200  ++otherTSOS;
1201  continue;
1202  }
1203 
1204  double dist = distAlongPars(*parsRef, *parsOther);
1205 
1206  if (dist > 0.) {
1207  prevDist = dist;
1208  prevPars = parsRef;
1209  ++refTSOS;
1210  continue;
1211  } else {
1212  const Trk::TrackParameters* closestPars = nullptr;
1213  if (prevPars && std::abs(prevDist) < std::abs(dist)) {
1214  closestPars = prevPars;
1215  } else {
1216  closestPars = parsRef;
1217  }
1218 
1219  // check whether state is a measurement
1220  const Trk::MeasurementBase* meas = (*otherTSOS)->measurementOnTrack();
1221  if (meas && (*otherTSOS)->type(Trk::TrackStateOnSurface::Measurement)) {
1222  Identifier id = m_edmHelperSvc->getIdentifier(*meas);
1223  // skip pseudo measurements
1224  if (!id.is_valid()) {
1225  prevDist = dist;
1226  prevPars = parsRef;
1227  ++otherTSOS;
1228  continue;
1229  }
1230  if (msgLvl(MSG::VERBOSE)) msg(MSG::VERBOSE) << m_idHelperSvc->toString(id);
1231  // unique ptr ownership retained. Original code deleted impactPars
1232  auto impactPars =
1233  m_propagator->propagate(ctx, *closestPars, meas->associatedSurface(),
1235  if (impactPars) {
1236  double residual = 1e10;
1237  double pull = 1e10;
1238  // pointer to resPull
1239  std::optional<Trk::ResidualPull> resPull =
1240  m_pullCalculator->residualPull(meas, impactPars.get(), Trk::ResidualPull::Unbiased);
1241  if (resPull && resPull->pull().size() == 1) {
1242  if (msgLvl(MSG::VERBOSE)) msg(MSG::VERBOSE) << " residual " << m_printer->print(*resPull);
1243  residual = resPull->residual().front();
1244  pull = resPull->pull().front();
1245  } else {
1246  ATH_MSG_WARNING("failed to calculate residual and pull");
1247  }
1248 
1249  bool inBounds = false;
1250  Amg::Vector2D LocVec2D;
1251  bool ok = meas->associatedSurface().globalToLocal(impactPars->position(), impactPars->momentum(), LocVec2D);
1252  // delete impactPars;
1253  if (ok) {
1254  if (msgLvl(MSG::VERBOSE))
1255  msg(MSG::VERBOSE) << " lpos (" << LocVec2D[Trk::locX] << "," << LocVec2D[Trk::locY] << ")";
1256  double tol1 = 50.;
1257  double tol2 = tol1;
1258  Identifier id = m_edmHelperSvc->getIdentifier(*meas);
1259  if (msgLvl(MSG::VERBOSE) && m_idHelperSvc->isMdt(id)) {
1260  const MdtDriftCircleOnTrack* mdt = dynamic_cast<const MdtDriftCircleOnTrack*>(meas);
1261  if (mdt) {
1262  int layer = m_idHelperSvc->mdtIdHelper().tubeLayer(id);
1263  int tube = m_idHelperSvc->mdtIdHelper().tube(id);
1264  double halfTubeLen = 0.5 * mdt->detectorElement()->getActiveTubeLength(layer, tube);
1265  if (msgLvl(MSG::VERBOSE)) msg(MSG::VERBOSE) << " range " << halfTubeLen;
1266  }
1267  }
1268 
1269  // for MM, perform the bound check from the detector element to take into account edge passivation
1270  const MMClusterOnTrack* mmClusterOnTrack = dynamic_cast<const MMClusterOnTrack*>(meas);
1271  if (mmClusterOnTrack) {
1272  inBounds = mmClusterOnTrack->detectorElement()->insideActiveBounds(id, LocVec2D, tol1, tol2);
1273  } else {
1274  inBounds = meas->associatedSurface().insideBounds(LocVec2D, tol1, tol2);
1275  }
1276 
1277  if (msgLvl(MSG::VERBOSE)) {
1278  if (inBounds)
1279  msg(MSG::VERBOSE) << " inBounds ";
1280  else
1281  msg(MSG::VERBOSE) << " outBounds ";
1282  }
1283  } else {
1284  ATH_MSG_WARNING("globalToLocal failed");
1285  }
1286 
1287  if (inBounds && (std::abs(residual) < 20. || std::abs(pull) < 10.)) {
1288  ATH_MSG_VERBOSE(" --> matching ");
1289  ++nmatching;
1290  } else {
1291  ATH_MSG_VERBOSE(" --> off ");
1292  ++noff;
1293  }
1294 
1295  } else {
1296  ATH_MSG_DEBUG("failed to extrapolate parameters to surface");
1297  }
1298  }
1299 
1300  prevDist = dist;
1301  prevPars = parsRef;
1302  ++otherTSOS;
1303  continue;
1304  }
1305  }
1306 
1307  // if more hits are compatible with reference track than are not consider as split track
1308  return nmatching > noff;
1309  }
1310 
1311  TrackCollection* MooTrackBuilder::mergeSplitTracks(const EventContext& ctx, const TrackCollection& tracks) const {
1312  // vector to store good track, boolean is used to identify whether the track was created in this routine or is from the collection
1313  std::vector<std::pair<bool, std::unique_ptr<Trk::Track> > > goodTracks;
1314  goodTracks.reserve(tracks.size());
1315  bool foundSplitTracks = false;
1316 
1317  ATH_MSG_DEBUG(" trying to merge split tracks, collection size " << tracks.size());
1318 
1319  // loop over tracks
1320  for (const Trk::Track* in_track : tracks) {
1321  // pointer to merged track
1322  std::unique_ptr<Trk::Track> mergedTrack;
1323 
1324  // compare them to all good tracks and look for split tracks
1325  for (std::pair<bool, std::unique_ptr<Trk::Track>>& good_trk : goodTracks) {
1326  // check whether track is split
1327  bool isSplit = isSplitTrack(ctx, *good_trk.second, *in_track);
1328  if (isSplit) {
1329  // if we found a potential split track, try to combine them
1330  std::unique_ptr<Trk::Track> track1 = std::make_unique<Trk::Track>(*good_trk.second);
1331  std::unique_ptr<Trk::Track> track2 = std::make_unique<Trk::Track>(*in_track);
1332  std::unique_ptr<MuPatTrack> can1 = m_candidateHandler->createCandidate(track1);
1333  std::unique_ptr<MuPatTrack> can2 = m_candidateHandler->createCandidate(track2);
1334  mergedTrack = combine(ctx, *can1, *can2, emptyPhiHits);
1335 
1336  // we have found a split track and have successfully merged it
1337  // replace the track in goodTracks with the new one
1338  if (mergedTrack) {
1339  ATH_MSG_DEBUG(" origninal tracks " << std::endl
1340  << m_printer->print(*good_trk.second) << std::endl
1341  << m_printer->printStations(*good_trk.second) << std::endl
1342  << m_printer->print(*in_track) << std::endl
1343  << m_printer->printStations(*in_track) << std::endl
1344  << " merged track " << std::endl
1345  << m_printer->print(*mergedTrack) << std::endl
1346  << m_printer->printStations(*mergedTrack));
1347  foundSplitTracks = true;
1348  // check whether this is a new track, if so delete the old one before overwriting it
1349  good_trk.first = true;
1350  good_trk.second.swap(mergedTrack);
1351  break;
1352  } else {
1353  ATH_MSG_VERBOSE(" failed to merge tracks " << std::endl
1354  << m_printer->print(*good_trk.second) << std::endl
1355  << m_printer->printStations(*good_trk.second) << std::endl
1356  << m_printer->print(*in_track) << std::endl
1357  << m_printer->printStations(*in_track));
1358  }
1359  }
1360  }
1361 
1362  // if this track was not merged with another track insert it into goodTracks
1363  if (!mergedTrack) {
1364  std::unique_ptr<Trk::Track> newTrack = std::make_unique<Trk::Track>(*in_track);
1365  goodTracks.emplace_back(false, std::move(newTrack));
1366  }
1367  }
1368 
1369  // did we find any?
1370  if (!foundSplitTracks) return nullptr;
1371  // loop over the new track vector and create a new TrackCollection
1372  TrackCollection* newTracks = new TrackCollection();
1373  newTracks->reserve(goodTracks.size());
1374  for (std::pair<bool, std::unique_ptr<Trk::Track>>& good_trk: goodTracks) {
1375  // TrackCollection will take ownership
1376  newTracks->push_back(std::move(good_trk.second));
1377  }
1378  return newTracks;
1379  }
1380 
1381 } // 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:1092
Trk::anyDirection
@ anyDirection
Definition: PropDirection.h:22
plotting.yearwise_luminosity_vs_mu.comp
comp
Definition: yearwise_luminosity_vs_mu.py:24
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
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
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:1311
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:257
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:43
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
Trk::locY
@ locY
local cartesian
Definition: ParamDefs.h:44
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.
Muon::MuonStationIndex::EO
@ EO
Definition: MuonStationIndex.h:26
Amg::Vector2D
Eigen::Matrix< double, 2, 1 > Vector2D
Definition: GeoPrimitives.h:48
drawFromPickle.candidates
candidates
Definition: drawFromPickle.py:271
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:615
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::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:423
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:56
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
This class provides conversion from CSC RDO data to CSC Digits.
Definition: TrackSystemController.h:49
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
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:917
ResidualPull.h
Muon::MuPatSegment::entryPars
const Trk::TrackParameters & entryPars() const
returns first track parameters
Definition: MuPatSegment.h:83
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
Identifier
Definition: DetectorDescription/Identifier/Identifier/Identifier.h:32
beamspotman.n
n
Definition: beamspotman.py:731
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:410
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: TrkEvent/TrkSegment/TrkSegment/Segment.h:166
Trk::Segment
Definition: 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:52
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:264
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:344
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::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:18
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:896
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...
Muon::MuonStationIndex::BO
@ BO
Definition: MuonStationIndex.h:25
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::MuonStationIndex::stName
static const std::string & stName(StIndex index)
convert StIndex into a string
Definition: MuonStationIndex.cxx:141
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::MuonStationIndex::StIndex
StIndex
enum to classify the different station layers in the muon spectrometer
Definition: MuonStationIndex.h:23
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:512
python.Constants.VERBOSE
int VERBOSE
Definition: Control/AthenaCommon/python/Constants.py:14
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:331
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:75
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:721
Muon::MooTrackBuilder::removeDuplicateWithReference
void removeDuplicateWithReference(std::unique_ptr< Trk::SegmentCollection > &segments, std::vector< const MuonSegment * > &referenceSegments) const
Definition: MooTrackBuilder.cxx:481
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:31
zero
void zero(TH2 *h)
zero the contents of a 2d histogram
Definition: comparitor.cxx:435
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
Muon::MuonStationIndex::EM
@ EM
Definition: MuonStationIndex.h:26
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