15 declareInterface<IMuonLayerAmbiguitySolverTool>(
this);
24 return StatusCode::SUCCESS;
28 std::vector<MuonCandidate>& resolvedCandidates)
const {
30 std::vector<std::vector<MuonLayerIntersection> > muonLayerDataHashVec;
34 unsigned int nseeds = 0;
35 std::set<const MuonSegment*> usedSegments;
36 std::vector<StIndex> inverseSeedLayerOrder = {StIndex::BO, StIndex::BI, StIndex::BM,
37 StIndex::EO, StIndex::EE, StIndex::EI, StIndex::EM};
41 if (!
getNextSeed(muonLayerDataHashVec, usedSegments, inverseSeedLayerOrder, layerIntersection)) {
47 std::vector<MuonLayerIntersection> layerIntersections ={ std::move(layerIntersection)};
48 std::vector<MuonCandidate> candidates = {
MuonCandidate(std::move(layerIntersections))};
51 ATH_MSG_DEBUG(
" Completed seed extension " << candidates.size());
52 if (
msgLvl(MSG::VERBOSE)) {
53 for (
const auto& candidate : candidates) {
54 msg(MSG::VERBOSE) <<
" Candidate with layers " << candidate.layerIntersections.size();
55 for (
const auto& entry : candidate.layerIntersections) {
56 msg(MSG::VERBOSE) << std::endl <<
" " <<
m_printer->print(*entry.segment);
63 for (
const auto& candidate : candidates) {
64 for (
const auto& layer : candidate.layerIntersections) { usedSegments.insert(layer.segment.get()); }
66 resolvedCandidates.insert(resolvedCandidates.end(), std::make_move_iterator(candidates.begin()),
67 std::make_move_iterator(candidates.end()));
72 ATH_MSG_DEBUG(
"Completed ambiguity solving using " << nseeds <<
" seeds, resulting in " << resolvedCandidates.size()
73 <<
" track candidates ");
77 const EventContext& ctx, std::vector<MuonCandidate>& candidates,
78 const std::vector<std::vector<MuonLayerIntersection> >& muonLayerDataHashVec,
79 const std::vector<MuonStationIndex::StIndex>& inverseSeedLayerOrder)
const {
81 if (inverseSeedLayerOrder.empty())
return true;
83 ATH_MSG_VERBOSE(
"extendCandidates " << candidates.size() <<
" remaining layers " << inverseSeedLayerOrder.size());
87 const std::vector<MuonLayerIntersection>& layerIntersections = muonLayerDataHashVec[
toInt(currentStIndex)];
88 if (!layerIntersections.empty()) {
90 std::vector<MuonCandidate> newCandidates;
95 unsigned int selectedSegmentsInLayer = 0;
100 if (
match(ctx, candidate, layerIntersection)) {
102 if (selectedSegmentsInLayer == 0) {
103 candidate.layerIntersections.push_back(layerIntersection);
108 newCandidates.emplace_back(std::move(newCandidate));
110 ++selectedSegmentsInLayer;
115 if (!newCandidates.empty()) {
116 ATH_MSG_VERBOSE(
"Found multiple solutions, add new candidates " << newCandidates.size());
117 candidates.insert(candidates.end(), std::make_move_iterator(newCandidates.begin()),
118 std::make_move_iterator(newCandidates.end()));
123 std::vector<MuonStationIndex::StIndex> newInverseSeedLayerOrder = inverseSeedLayerOrder;
124 newInverseSeedLayerOrder.pop_back();
138 std::set<const MuonSegment*>& usedSegments,
139 std::vector<MuonStationIndex::StIndex>& inverseSeedLayerOrder,
141 ATH_MSG_VERBOSE(
"getNextSeed, remaining layers " << inverseSeedLayerOrder.size());
143 std::vector<MuonStationIndex::StIndex>::const_reverse_iterator rit = inverseSeedLayerOrder.rbegin();
144 std::vector<MuonStationIndex::StIndex>::const_reverse_iterator rit_end = inverseSeedLayerOrder.rend();
145 for (; rit != rit_end; ++rit) {
151 const MuonSegment* segment = muonLayerIntersection.segment.get();
152 if (usedSegments.count(segment))
continue;
153 usedSegments.insert(segment);
156 layerIntersection = muonLayerIntersection;
161 inverseSeedLayerOrder.pop_back();
167 std::vector<std::vector<MuonLayerIntersection> >& muonLayerDataHashVec)
const {
169 muonLayerDataHashVec.clear();
170 muonLayerDataHashVec.resize(
toInt(StIndex::StIndexMax));
178 std::vector<MuonLayerIntersection> layerIntersections;
179 layerIntersections.reserve(layer.segments.size());
180 for (
const std::shared_ptr<const MuonSegment>& segment : layer.segments) {
184 layerIntersections.emplace_back(layer.intersection, segment, quality);
188 if (muonLayerDataHashVec[
toInt(stIndex)].
empty()) {
189 muonLayerDataHashVec[
toInt(stIndex)] = std::move(layerIntersections);
196 std::ranges::stable_sort(muonLayerDataHashVec[
toInt(stIndex)],
201 msg(MSG::DEBUG) <<
" Done building segment vector ";
202 for (
const auto&
vec : muonLayerDataHashVec) {
203 for (
const auto& entry :
vec) {
msg(MSG::DEBUG) << std::endl <<
" " <<
m_printer->print(*entry.segment); }
210 std::vector<MuonLayerIntersection>& existingLayerIntersections,
211 std::vector<MuonLayerIntersection>& newLayerIntersections)
const {
212 ATH_MSG_VERBOSE(
" resolveSmallLargeOverlaps: existing " << existingLayerIntersections.size() <<
" new "
213 << newLayerIntersections.size());
216 std::set<const MuonSegment*> combinedSegments;
217 std::vector<MuonLayerIntersection> combinedIntersections;
231 if (!
m_segmentMatchingTool->match(ctx, *layerIntersection1.segment, *layerIntersection2.segment))
continue;
235 std::shared_ptr<const MuonSegment> newseg{
236 m_muonTrackBuilder->combineToSegment(ctx, *layerIntersection1.segment, *layerIntersection2.segment, emptyVec)};
255 if (qualitynew < layerIntersection1.quality || qualitynew < layerIntersection2.quality) {
256 ATH_MSG_DEBUG(
"Quality got worse after combination: new " << qualitynew <<
" q1 " << layerIntersection1.quality
257 <<
" q2 " << layerIntersection2.quality);
269 double dist1 = getDistance(layerIntersection1, direction);
270 double dist2 = getDistance(layerIntersection2, direction);
272 combinedIntersections.emplace_back(layerIntersection1.intersection, newseg, qualitynew);
274 combinedIntersections.emplace_back(layerIntersection2.intersection, newseg, qualitynew);
277 <<
" first " <<
m_printer->print(*layerIntersection1.segment) << std::endl
278 <<
" second " <<
m_printer->print(*layerIntersection2.segment) << std::endl
279 <<
" combined " <<
m_printer->print(*newseg));
282 combinedSegments.insert(layerIntersection1.segment.get());
283 combinedSegments.insert(layerIntersection2.segment.get());
289 return !combinedSegments.count(inter_sect.segment.get());
292 combinedIntersections.reserve(existingLayerIntersections.size() + newLayerIntersections.size());
293 std::copy_if(std::make_move_iterator(existingLayerIntersections.begin()), std::make_move_iterator(existingLayerIntersections.end()),
294 std::back_inserter(combinedIntersections), insert_intersection);
295 std::copy_if(std::make_move_iterator(newLayerIntersections.begin()), std::make_move_iterator(newLayerIntersections.end()),
296 std::back_inserter(combinedIntersections), insert_intersection);
297 existingLayerIntersections = std::move(combinedIntersections);
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_VERBOSE(x,...)
std::vector< size_t > vec
static const Attributes_t empty
bool msgLvl(const MSG::Level lvl) const
std::vector< const Trk::PrepRawData * > PrepVec
This is the common class for 3D segments used in the muon spectrometer.
Class to represent and store fit qualities from track reconstruction in terms of and number of degre...
int numberDoF() const
returns the number of degrees of freedom of the overall track or vertex fit as integer
double chiSquared() const
returns the of the overall track fit
Eigen::Matrix< double, 3, 1 > Vector3D
StIndex
enum to classify the different station layers in the muon spectrometer
StIndex toStationIndex(ChIndex index)
convert ChIndex into StIndex
constexpr int toInt(const EnumType enumVal)
NRpcCablingAlg reads raw condition data and writes derived condition data to the condition store.
std::vector< MuonLayerIntersection > layerIntersections
MuonLayerIntersections.
std::shared_ptr< const MuonSegment > segment
segment
MuonSystemExtension::Intersection intersection
intersection with layer
std::shared_ptr< const Trk::TrackParameters > trackParameters