ATLAS Offline Software
Loading...
Searching...
No Matches
MuonCandidateTrackBuilderTool.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
12#include "TrkTrack/Track.h"
13namespace Muon {
14
15 MuonCandidateTrackBuilderTool::MuonCandidateTrackBuilderTool(const std::string& type, const std::string& name,
16 const IInterface* parent) :
17 AthAlgTool(type, name, parent) {
18 declareInterface<IMuonCandidateTrackBuilderTool>(this);
19 }
20
22 ATH_CHECK(m_printer.retrieve());
23 ATH_CHECK(m_idHelperSvc.retrieve());
24 ATH_CHECK(m_edmHelperSvc.retrieve());
25 ATH_CHECK(m_trackFitter.retrieve());
26 return StatusCode::SUCCESS;
27 }
28
29 std::unique_ptr<Trk::Track> MuonCandidateTrackBuilderTool::buildCombinedTrack(const EventContext& ctx, const Trk::Track& idTrack,
30 const MuonCandidate& candidate) const {
31 ATH_MSG_DEBUG("Building track from candidate with " << candidate.layerIntersections.size() << " layers ");
32 // copy and sort layerIntersections according to their distance to the IP
33 std::vector<MuonLayerIntersection> layerIntersections = candidate.layerIntersections;
34 std::stable_sort(layerIntersections.begin(), layerIntersections.end(),
35 [](const MuonLayerIntersection& lay1, const MuonLayerIntersection& lay2) {
36 auto getDistance = [](const MuonLayerIntersection& layerIntersection) {
37 if (layerIntersection.intersection.trackParameters.get() == nullptr) return 1e9;
38 return layerIntersection.intersection.trackParameters->position().mag();
39 };
40 return getDistance(lay1) < getDistance(lay2);
41 });
42
43 // loop over sorted layers and extract measurements
44 std::vector<const Trk::MeasurementBase*> measurements;
45 int intersec = 0;
46 bool isEndcap{false}, isBarrel{false}, isSmall{false}, isLarge{false};
47 for (const MuonLayerIntersection& layerIntersection : layerIntersections) {
48 intersec++;
49 ATH_MSG_VERBOSE(" layerIntersection " << intersec << " perp "
50 << layerIntersection.intersection.trackParameters->position().perp() << " z "
51 << layerIntersection.intersection.trackParameters->position().z() << " distance to IP "
52 << layerIntersection.intersection.trackParameters->position().mag());
53 ATH_MSG_VERBOSE(" segment surface center perp " << layerIntersection.segment->associatedSurface().center().perp() << " z "
54 << layerIntersection.segment->associatedSurface().center().z() << " nr of msts "
55 << layerIntersection.segment->containedMeasurements().size());
56 ATH_MSG_VERBOSE(m_printer->print(*(layerIntersection.segment)));
57
58 // Fix problem with segments where measurements are not ordered wrt IP
59
60 // first check whether it is a Barrel or Endcap segment
61
62 std::vector<const Trk::MeasurementBase*> containedMeasurements = layerIntersection.segment->containedMeasurements();
63 for (const Trk::MeasurementBase* mit : containedMeasurements) {
64 // get Identifier
65 Identifier id;
66 const Trk::RIO_OnTrack* rio = dynamic_cast<const Trk::RIO_OnTrack*>(mit);
67 if (rio)
68 id = rio->identify();
69 else {
70 const Trk::CompetingRIOsOnTrack* crio = dynamic_cast<const Trk::CompetingRIOsOnTrack*>(mit);
71 if (crio)
72 id = crio->rioOnTrack(0).identify();
73 else
74 continue;
75 }
76 // check if valid ID
77 if (!id.is_valid()) continue;
78 // check if muon
79 if (!m_idHelperSvc->isMuon(id)) continue;
80
81 if (m_idHelperSvc->isEndcap(id)) {
82 isEndcap = true;
83 } else {
84 isBarrel = true;
85 }
86 if (m_idHelperSvc->isTrigger(id)) continue;
87
88 if (m_idHelperSvc->isSmallChamber(id)) {
89 isSmall = true;
90 } else {
91 isLarge = true;
92 }
93 }
94
95 if (m_reOrderMeasurements) {
96 // reorder measurements using SortMeas (defined in header file)
97 std::stable_sort(containedMeasurements.begin(), containedMeasurements.end(),
98 SortMeas(&*m_edmHelperSvc, &*m_idHelperSvc, isEndcap));
99 }
100 // insert in measurements list
101 measurements.insert(measurements.end(), containedMeasurements.begin(), containedMeasurements.end());
102 }
103
104 // check for rare case in which 2 layers are large/small and one segment contains the other only with the opposite assignment of
105 // radius signs
106 if (candidate.layerIntersections.size() == 2 && isSmall && isLarge) {
107 if (m_idHelperSvc->stationIndex(m_edmHelperSvc->chamberId(*candidate.layerIntersections.at(0).segment)) ==
108 m_idHelperSvc->stationIndex(m_edmHelperSvc->chamberId(*candidate.layerIntersections.at(1).segment))) {
109 const Muon::MuonSegment* seg1 = candidate.layerIntersections.at(0).segment.get();
110 const Muon::MuonSegment* seg2 = candidate.layerIntersections.at(1).segment.get();
111 if (seg1->containedMeasurements().size() > seg2->containedMeasurements().size()) {
112 seg2 = candidate.layerIntersections.at(0).segment.get();
113 seg1 = candidate.layerIntersections.at(1).segment.get();
114 }
115 bool found = false;
116 for (const auto& meas1 : seg1->containedMeasurements()) {
117 found = false;
118 for (const auto& meas2 : seg2->containedMeasurements()) {
119 if (m_edmHelperSvc->getIdentifier(*meas1) == m_edmHelperSvc->getIdentifier(*meas2)) {
120 found = true;
121 break;
122 }
123 }
124 // if any hit isn't found we're off the hook
125 if (!found) break;
126 }
127 if (found) {
128 ATH_MSG_DEBUG("S/L overlap where one segment contains the other, don't use");
129 return std::unique_ptr<Trk::Track>();
130 }
131 }
132 }
133
134 // reorder in case of Small Large overlaps in Barrel or Endcap ONLY
135
136 bool reorderAllMeasurements = false;
137 if (isSmall && isLarge) reorderAllMeasurements = true;
138 if (isEndcap && isBarrel) reorderAllMeasurements = false;
139
140 if (m_reOrderMeasurements && reorderAllMeasurements) {
141 // reorder measurements using SortMeas (defined in header file)
142 ATH_MSG_VERBOSE(" reorder all measurements before " << std::endl << m_printer->print(measurements));
143 std::stable_sort(measurements.begin(), measurements.end(), SortMeas(&*m_edmHelperSvc, &*m_idHelperSvc, isEndcap));
144 }
145
146 ATH_MSG_VERBOSE("final measurement list: " << std::endl << m_printer->print(measurements));
147
148 ATH_MSG_DEBUG("Extracted hits from candidate: " << measurements.size());
149 std::unique_ptr<Trk::Track> refittedTrack{m_trackFitter->indetExtension(ctx, idTrack, measurements)};
150 if (refittedTrack) {
151 ATH_MSG_DEBUG("got Track: " << m_printer->print(*refittedTrack) << std::endl << m_printer->printStations(*refittedTrack));
152 }
153 return refittedTrack;
154 }
155} // namespace Muon
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_DEBUG(x)
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
ServiceHandle< IMuonEDMHelperSvc > m_edmHelperSvc
PublicToolHandle< MuonEDMPrinterTool > m_printer
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
ToolHandle< Rec::ICombinedMuonTrackBuilder > m_trackFitter
MuonCandidateTrackBuilderTool(const std::string &type, const std::string &name, const IInterface *parent)
Default AlgTool functions.
virtual std::unique_ptr< Trk::Track > buildCombinedTrack(const EventContext &ctx, const Trk::Track &idTrack, const MuonCandidate &candidate) const override
IMuonCandidateTrackBuilderTool interface: buildCombinedTrack.
virtual const RIO_OnTrack & rioOnTrack(unsigned int) const =0
returns the RIO_OnTrack (also known as ROT) objects depending on the integer.
Identifier identify() const
return the identifier -extends MeasurementBase
const std::vector< const Trk::MeasurementBase * > & containedMeasurements() const
returns the vector of Trk::MeasurementBase objects
bool isSmall(const ChIndex index)
Returns true if the chamber index is in a small sector.
bool isBarrel(const ChIndex index)
Returns true if the chamber index points to a barrel chamber.
NRpcCablingAlg reads raw condition data and writes derived condition data to the condition store.
void stable_sort(DataModel_detail::iterator< DVL > beg, DataModel_detail::iterator< DVL > end)
Specialization of stable_sort for DataVector/List.