ATLAS Offline Software
MuonCandidateTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 // MuonCandidateTool
7 // AlgTool performing pre-selection on MS tracks, extrapolation and creation
8 // of MuonCandidate collection.
9 //
11 
12 #include "MuonCandidateTool.h"
13 
15 
16 namespace {
17  // Temporary collection for extrapolated tracks and links with correspondent MS tracks
18  struct track_link {
19  std::unique_ptr<Trk::Track> track;
20  unsigned int container_index;
21  bool extp_succeed;
22  track_link(std::unique_ptr<Trk::Track> _trk, unsigned int _idx, bool _succeed) :
23  track{std::move(_trk)}, container_index{_idx}, extp_succeed{_succeed} {}
24  };
25 } // namespace
26 
27 namespace MuonCombined {
28 
29  MuonCandidateTool::MuonCandidateTool(const std::string& type, const std::string& name, const IInterface* parent) :
31  declareInterface<IMuonCandidateTool>(this);
32  }
33 
35  ATH_CHECK(m_printer.retrieve());
36  if (!m_trackBuilder.empty())
37  ATH_CHECK(m_trackBuilder.retrieve());
38  else
39  m_trackBuilder.disable();
40  if (!m_trackExtrapolationTool.empty())
42  else
43  m_trackExtrapolationTool.disable();
44  ATH_CHECK(m_ambiguityProcessor.retrieve());
45  ATH_CHECK(m_trackSummaryTool.retrieve());
46  ATH_CHECK(m_idHelperSvc.retrieve());
48 
49  ATH_CHECK(m_segmentKey.initialize(!m_segmentKey.empty()));
50  if (!m_segmentKey.empty()) { ATH_CHECK(m_trackSegmentAssociationTool.retrieve()); }
51  return StatusCode::SUCCESS;
52  }
54  TrackCollection& outputTracks, const EventContext& ctx) const {
55  ATH_MSG_DEBUG("Producing MuonCandidates for " << tracks.size());
56  unsigned int ntracks = 0;
57 
59  if (!beamSpotHandle.isValid()) {
60  ATH_MSG_ERROR("Could not retrieve the BeamSpot data from key " << m_beamSpotKey.objKey());
61  return;
62  }
63 
64  ATH_MSG_DEBUG("Beamspot position bs_x=" << beamSpotHandle->beamPos());
65 
66  std::vector<track_link> trackLinks;
67 
68  unsigned int index = -1;
69  // Loop over MS tracks
70  for (const auto* track : tracks) {
71  ++index;
72 
73  if (!track->trackLink().isValid() || !track->track()) {
74  ATH_MSG_WARNING("MuonStandalone track particle without Trk::Track");
75  continue;
76  }
77  const Trk::Track& msTrack = *track->track();
78 
79  ATH_MSG_VERBOSE("Re-Fitting track " << std::endl
80  << m_printer->print(msTrack) << std::endl
81  << m_printer->printStations(msTrack));
82  std::unique_ptr<Trk::Track> standaloneTrack;
83  if (m_extrapolationStrategy == 0u) {
84  standaloneTrack = m_trackBuilder->standaloneFit(ctx, msTrack, beamSpotHandle->beamPos(), nullptr);
85  } else {
86  standaloneTrack = m_trackExtrapolationTool->extrapolate(msTrack, ctx);
87  }
88  if (standaloneTrack) {
89  // Reject the track if its fit quality is much (much much) worse than that of the non-extrapolated track
90  if (standaloneTrack->fitQuality()->doubleNumberDoF() == 0) {
91  standaloneTrack.reset();
92  ATH_MSG_DEBUG("extrapolated track has no DOF, don't use it");
93  } else {
94  double mschi2 = 2.5; // a default we should hopefully never have to use (taken from CombinedMuonTrackBuilder)
95  if (msTrack.fitQuality()->doubleNumberDoF() > 0)
96  mschi2 = msTrack.fitQuality()->chiSquared() / msTrack.fitQuality()->doubleNumberDoF();
97  // choice of 1000 is slightly arbitrary, the point is that the fit should be really be terrible
98  if (standaloneTrack->fitQuality()->chiSquared() / standaloneTrack->fitQuality()->doubleNumberDoF() > 1000 * mschi2) {
99  standaloneTrack.reset();
100  ATH_MSG_DEBUG("extrapolated track has a degraded fit, don't use it");
101  }
102  }
103  }
104  if (standaloneTrack) {
105  standaloneTrack->info().setParticleHypothesis(Trk::muon);
107  ATH_MSG_VERBOSE("Extrapolated track " << std::endl
108  << m_printer->print(*standaloneTrack) << std::endl
109  << m_printer->printStations(*standaloneTrack));
110  ++ntracks;
111  if (!standaloneTrack->perigeeParameters())
112  ATH_MSG_WARNING(" Track without perigee " << (*standaloneTrack));
113  else if (!standaloneTrack->perigeeParameters()->covariance())
114  ATH_MSG_WARNING(" Track with perigee without covariance " << (*standaloneTrack));
115  trackLinks.emplace_back(std::move(standaloneTrack), index, true);
116  } else {
117  // We can create tracks from EM segments+TGC hits
118  // If these are not successfully extrapolated, they are too low quality to be useful
119  // So only make candidates from un-extrapolated tracks if they are not EM-only
120  bool skipTrack = true;
121  const Trk::MuonTrackSummary* msMuonTrackSummary = nullptr;
122  std::unique_ptr<Trk::TrackSummary> msTrackSummary;
123  // If reading from an ESD, the track will not have a track summary yet
124  if (!msTrack.trackSummary()) {
125  msTrackSummary = m_trackSummaryTool->summary(msTrack);
126  msMuonTrackSummary = msTrackSummary->muonTrackSummary();
127  } else
128  msMuonTrackSummary = msTrack.trackSummary()->muonTrackSummary();
129  for (const auto& chs : msMuonTrackSummary->chamberHitSummary()) {
130  if ((chs.isMdt() && m_idHelperSvc->stationIndex(chs.chamberId()) != Muon::MuonStationIndex::EM) ||
131  m_idHelperSvc->isCsc(chs.chamberId())) {
132  skipTrack = false;
133  break;
134  }
135  }
136  if (!skipTrack) { trackLinks.emplace_back(std::make_unique<Trk::Track>(msTrack), index, false); }
137  }
138  }
140  std::unique_ptr<TrackCollection> extrapTracks = std::make_unique<TrackCollection>(SG::VIEW_ELEMENTS);
141  extrapTracks->reserve(trackLinks.size());
142  for (const track_link& link : trackLinks) extrapTracks->push_back(link.track.get());
143  ATH_MSG_DEBUG("Finished back-tracking, total number of successfull fits " << ntracks);
144 
145  // Resolve ambiguity between extrapolated tracks (where available)
146  std::unique_ptr<const TrackCollection> resolvedTracks(m_ambiguityProcessor->process(extrapTracks.get()));
147 
148  ATH_MSG_DEBUG("Finished ambiguity solving: " << extrapTracks->size() << " track(s) in -> " << resolvedTracks->size()
149  << " track(s) out");
150 
151  const Trk::SegmentCollection* segments{nullptr};
152  if (!m_segmentKey.empty()) {
154  if (!readHandle.isValid()) {
155  ATH_MSG_WARNING("Failed to retrieve the segment container " << m_segmentKey.fullKey());
156  } else
157  segments = readHandle.cptr();
158  }
159 
160  // Loop over resolved tracks and build MuonCondidate collection
161  for (const Trk::Track* track : *resolvedTracks) {
163  std::find_if(trackLinks.begin(), trackLinks.end(), [&track](const track_link& link) { return link.track.get() == track; });
164 
165  if (tLink == trackLinks.end()) {
166  ATH_MSG_WARNING("Unable to find internal link between MS and SA tracks!");
167  continue;
168  }
169 
170  std::unique_ptr<MuonCandidate> muon_candidate;
171  ElementLink<xAOD::TrackParticleContainer> MS_TrkLink{tracks, tLink->container_index, ctx};
172  if (tLink->extp_succeed) {
173  outputTracks.push_back(std::move(tLink->track));
174  ElementLink<TrackCollection> saLink(outputTracks, outputTracks.size() - 1, ctx);
175  muon_candidate = std::make_unique<MuonCandidate>(MS_TrkLink, saLink, outputTracks.size() - 1);
176  // remove track from set so it is not deleted
177  } else {
178  // in this case the extrapolation failed
179  muon_candidate = std::make_unique<MuonCandidate>(MS_TrkLink);
180  }
181  muon_candidate->setCommissioning(m_commissioning);
183  if (segments) {
184  std::vector<const Muon::MuonSegment*> assoc_segs;
185  m_trackSegmentAssociationTool->associatedSegments(*muon_candidate->primaryTrack(), segments, assoc_segs);
186  muon_candidate->setSegments(std::move(assoc_segs));
187  }
188 
189  outputCollection.push_back(std::move(muon_candidate));
190  }
191  }
192 
193 } // namespace MuonCombined
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
MuonCombined::MuonCandidateTool::m_commissioning
Gaudi::Property< bool > m_commissioning
Definition: MuonCandidateTool.h:56
Trk::Track::fitQuality
const FitQuality * fitQuality() const
return a pointer to the fit quality const-overload
MuonCombined::MuonCandidateTool::m_idHelperSvc
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
Definition: MuonCandidateTool.h:45
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
MuonTrackSummary.h
Trk::Track
The ATLAS Track class.
Definition: Tracking/TrkEvent/TrkTrack/TrkTrack/Track.h:73
SG::VIEW_ELEMENTS
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
Definition: OwnershipPolicy.h:18
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
index
Definition: index.py:1
MuonCandidateTool.h
Trk::Track::info
const TrackInfo & info() const
Returns a const ref to info of a const tracks.
MuonCombined::MuonCandidateTool::m_trackBuilder
ToolHandle< Rec::ICombinedMuonTrackBuilder > m_trackBuilder
Definition: MuonCandidateTool.h:38
Trk::TrackInfo::MuidStandAlone
@ MuidStandAlone
MuidStandalone.
Definition: Tracking/TrkEvent/TrkTrack/TrkTrack/TrackInfo.h:165
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
MuonCombined::MuonCandidateTool::initialize
virtual StatusCode initialize() override
Definition: MuonCandidateTool.cxx:34
Trk::u
@ u
Enums for curvilinear frames.
Definition: ParamDefs.h:83
Trk::MuonTrackSummary::chamberHitSummary
const std::vector< ChamberHitSummary > & chamberHitSummary() const
access to the vector of chamber hit summaries on the track
Definition: MuonTrackSummary.h:148
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
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
MuonCombined::MuonCandidateTool::m_printer
ToolHandle< Muon::MuonEDMPrinterTool > m_printer
Definition: MuonCandidateTool.h:37
test_pyathena.parent
parent
Definition: test_pyathena.py:15
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
Trk::MuonTrackSummary
Detailed track summary for the muon system Give access to hit counts per chamber.
Definition: MuonTrackSummary.h:26
Trk::muon
@ muon
Definition: ParticleHypothesis.h:28
DataVector< xAOD::TrackParticle_v1 >
postInclude.outputCollection
outputCollection
Definition: postInclude.SortInput.py:27
Trk::Track::perigeeParameters
const Perigee * perigeeParameters() const
return Perigee.
Definition: Tracking/TrkEvent/TrkTrack/src/Track.cxx:163
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:192
MuonCombined::MuonCandidateTool::MuonCandidateTool
MuonCandidateTool(const std::string &type, const std::string &name, const IInterface *parent)
Definition: MuonCandidateTool.cxx:29
DataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
MuonCombined::MuonCandidateTool::m_trackSegmentAssociationTool
PublicToolHandle< MuonCombined::IMuonTrackToSegmentAssociationTool > m_trackSegmentAssociationTool
Definition: MuonCandidateTool.h:51
MuonCombined::MuonCandidateTool::m_extrapolationStrategy
Gaudi::Property< unsigned int > m_extrapolationStrategy
Definition: MuonCandidateTool.h:54
DeMoScan.index
string index
Definition: DeMoScan.py:362
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
Trk::Track::trackSummary
const Trk::TrackSummary * trackSummary() const
Returns a pointer to the const Trk::TrackSummary owned by this const track (could be nullptr)
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
MuonCombined
The MuonTagToSegMap is an auxillary construct that links the MuonSegments associated with a combined ...
Definition: IMuonSystemExtensionTool.h:23
MuonCombined::MuonCandidateTool::m_trackExtrapolationTool
ToolHandle< Muon::IMuonTrackExtrapolationTool > m_trackExtrapolationTool
Definition: MuonCandidateTool.h:39
Trk::TrackInfo::setParticleHypothesis
void setParticleHypothesis(const ParticleHypothesis &hypothesis)
Method re-setting the ParticleHypothesis.
Trk::FitQuality::chiSquared
double chiSquared() const
returns the of the overall track fit
Definition: FitQuality.h:56
xAOD::track
@ track
Definition: TrackingPrimitives.h:512
Trk::TrackInfo::setPatternRecognitionInfo
void setPatternRecognitionInfo(const TrackPatternRecoInfo &patternReco)
Method setting the pattern recognition algorithm.
AthAlgTool
Definition: AthAlgTool.h:26
Trk::TrackSummary::muonTrackSummary
const MuonTrackSummary * muonTrackSummary() const
returns a pointer to the MuonTrackSummary if available
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
MuonCombined::MuonCandidateTool::m_segmentKey
SG::ReadHandleKey< Trk::SegmentCollection > m_segmentKey
Retrieve the segment container to perform the segment association offline.
Definition: MuonCandidateTool.h:50
Muon::MuonStationIndex::EM
@ EM
Definition: MuonStationIndex.h:26
MuonCombined::MuonCandidateTool::m_beamSpotKey
SG::ReadCondHandleKey< InDet::BeamSpotData > m_beamSpotKey
Definition: MuonCandidateTool.h:47
MuonCombined::MuonCandidateTool::m_ambiguityProcessor
ToolHandle< Trk::ITrackAmbiguityProcessorTool > m_ambiguityProcessor
Definition: MuonCandidateTool.h:41
Trk::FitQuality::doubleNumberDoF
double doubleNumberDoF() const
returns the number of degrees of freedom of the overall track or vertex fit as double
Definition: FitQuality.h:68
MuonCombined::MuonCandidateTool::m_trackSummaryTool
ToolHandle< Trk::IExtendedTrackSummaryTool > m_trackSummaryTool
Definition: MuonCandidateTool.h:43
MuonCombined::MuonCandidateTool::create
virtual void create(const xAOD::TrackParticleContainer &tracks, MuonCandidateCollection &outputCollection, TrackCollection &outputTracks, const EventContext &ctx) const override
IMuonCandidateTool interface: build a MuonCandidateCollection from a TrackCollection of spectrometer ...
Definition: MuonCandidateTool.cxx:53