ATLAS Offline Software
Loading...
Searching...
No Matches
SegmentAmbiSolver.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
5#include <Acts/Utilities/Enumerate.hpp>
6
7namespace MuonR4::SegmentFit {
9
10 SegmentAmbiSolver::SegmentAmbiSolver(const std::string& name, Config&& cfg):
11 AthMessaging{name},
12 m_cfg{std::move(cfg)} {}
13
14 double SegmentAmbiSolver::redChi2(const Segment& segment) const {
15 return segment.chi2() / std::max(segment.nDoF(), 1u);
16 }
18 SegmentVec&& toResolve) const {
19
22 std::ranges::stable_sort(toResolve,[this](const SegmentVec::value_type& a,
23 const SegmentVec::value_type& b){
24 const double redChi2A = redChi2(*a);
25 const double redChi2B = redChi2(*b);
26 if (redChi2A < m_cfg.selectByNDoFChi2 && redChi2B < m_cfg.selectByNDoFChi2){
27 return a->nDoF() > b->nDoF();
28 }
29 return redChi2A < redChi2B;
30 });
31 SegmentVec resolved{};
32
34 resolved.push_back(std::move(toResolve[0]));
35 toResolve.erase(toResolve.begin());
36 std::vector<std::vector<int>> segmentSigns{driftSigns(gctx, *resolved.front(), resolved.front()->measurements())};
37 std::vector<MeasurementSet> segMeasurements{extractPrds(*resolved.front())};
38
39 for (SegmentVec::value_type& resolveMe : toResolve) {
40 ATH_MSG_VERBOSE("Try to resolve new segment "<<toString(localSegmentPars(gctx, *resolveMe))
41 <<" redChi2: "<<redChi2(*resolveMe)<<" nDoF: "<<resolveMe->nDoF());
43 MeasurementSet testMeas{extractPrds(*resolveMe)};
45 unsigned resolvedIdx{0};
46 for (SegmentVec::value_type& goodSeg : resolved) {
47 ATH_MSG_VERBOSE("Test against segment "<<toString(localSegmentPars(gctx, *goodSeg))
48 <<" redChi2: "<<redChi2(*goodSeg)<<" nDoF: "<<goodSeg->nDoF());
49 MeasurementSet& resolvedM = segMeasurements[resolvedIdx];
50 std::vector<int>& existSigns{segmentSigns[resolvedIdx++]};
52 unsigned shared = countShared(resolvedM, testMeas);
53 if (shared < m_cfg.sharedPrecHits) {
54 ATH_MSG_VERBOSE("Too few shared measurements "<<shared<<" (Required: "<<m_cfg.sharedPrecHits<<").");
55 continue;
56 }
58 const std::vector<int> reEvaluatedSigns{driftSigns(gctx, *resolveMe, goodSeg->measurements())};
59
60 unsigned sameSides{0};
61 for (unsigned s =0 ; s < existSigns.size(); ++s) {
62 sameSides += (reEvaluatedSigns[s] == existSigns[s]);
63 }
65 if (!m_cfg.remLeftRightAmbi && sameSides != existSigns.size() && resolveMe->nDoF() == goodSeg->nDoF()) {
66 ATH_MSG_VERBOSE("Reference signs: "<<existSigns<<" / re-evaluated: "<<reEvaluatedSigns);
67 continue;
68 }
69 const double resolvedChi2 = redChi2(*goodSeg);
70 const double resolveMeChi2 = redChi2(*resolveMe);
71 reso = resolveMeChi2 < resolvedChi2 ? Resolution::superSet : Resolution::subSet;
72
73 ATH_MSG_VERBOSE("Chi2 good "<<resolvedChi2<<", candidate chi2: "<<resolveMeChi2);
76 if (resolveMeChi2 < m_cfg.selectByNDoFChi2 && resolvedChi2 < m_cfg.selectByNDoFChi2) {
77 reso = goodSeg->nDoF() > resolveMe->nDoF() ? Resolution::subSet : Resolution::superSet;
78 }
79 if (reso == Resolution::superSet) {
80 std::swap(goodSeg, resolveMe);
81 std::swap(resolvedM, testMeas);
82 existSigns = driftSigns(gctx, *resolveMe, resolveMe->measurements());
83 break;
84 } else if (reso == Resolution::subSet) {
85 break;
86 }
87 }
89 if (reso == Resolution::noOverlap) {
90 segMeasurements.push_back(std::move(testMeas));
91 segmentSigns.push_back(driftSigns(gctx, *resolveMe, resolveMe->measurements()));
92 resolved.push_back(std::move(resolveMe));
93 }
94 }
95 return resolved;
96 }
98 const Segment& segment,
99 const Segment::MeasVec& measurements) const {
100 const auto [pos, dir] = makeLine(localSegmentPars(gctx, segment));
101
102 ATH_MSG_VERBOSE("Fetch drift signs for segment "<<segment.msSector()->identString()
103 <<" -- "<<Amg::toString(pos)<<" + " <<Amg::toString(dir));
104 return SeedingAux::strawSigns(pos, dir, measurements);
105 }
108
109 MeasurementSet meas{};
110 for (const Segment::MeasVec::value_type& hit : segment.measurements()) {
111 if (!hit->spacePoint() || hit->fitState() != CalibratedSpacePoint::State::Valid || !hit->measuresEta()) {
112 continue;
113 }
114 meas.insert(hit->spacePoint()->primaryMeasurement());
115 if (hit->spacePoint()->secondaryMeasurement()) {
116 meas.insert(hit->spacePoint()->secondaryMeasurement());
117 }
118 }
119 return meas;
120 }
122 const MeasurementSet& measSet2) const {
123 if (measSet1.size() > measSet2.size()) {
124 return std::count_if(measSet2.begin(),measSet2.end(),[&measSet1](const xAOD::UncalibratedMeasurement* meas){
125 return measSet1.count(meas);
126 });
127 }
128 return std::count_if(measSet1.begin(),measSet1.end(),[&measSet2](const xAOD::UncalibratedMeasurement* meas){
129 return measSet2.count(meas);
130 });
131 }
132}
#define ATH_MSG_VERBOSE(x)
static Double_t a
AthMessaging(IMessageSvc *msgSvc, const std::string &name)
Constructor.
std::string identString() const
Returns a string encoding the chamber index & the sector of the MS sector.
const Config m_cfg
Configuration object.
std::unordered_set< const xAOD::UncalibratedMeasurement * > MeasurementSet
List of measurements out of which the segment is made of.
Resolution
Auxiliary enum to indicate the ambiguity status of the segment candidates.
@ superSet
No ambiguity with other candidates detected.
@ subSet
Ambiguity detected and the candidate is of better quality.
SegmentVec resolveAmbiguity(const ActsTrk::GeometryContext &gctx, SegmentVec &&toResolve) const
Launches the ambiguity resoltuion and returns a new temporary contained containing the good candidate...
unsigned int countShared(const MeasurementSet &measSet1, const MeasurementSet &measSet2) const
Counts the number of measurements that're in both sets.
MeasurementSet extractPrds(const Segment &segment) const
Extract the Uncalibrated measurements used to build the segment.
double redChi2(const Segment &segment) const
Returns the reduced chi2 of the segment.
std::vector< std::unique_ptr< Segment > > SegmentVec
Abrivation of the temporary segment container.
std::vector< int > driftSigns(const ActsTrk::GeometryContext &gctx, const Segment &segment, const Segment::MeasVec &measurements) const
Calculates the left-right ambiguities of the segment w.r.t each measurement.
SegmentAmbiSolver(const std::string &name, Config &&config)
Constructor.
Placeholder for what will later be the muon segment EDM representation.
unsigned int nDoF() const
Returns the number of degrees of freedom.
const MuonGMR4::SpectrometerSector * msSector() const
Returns the associated MS sector.
const MeasVec & measurements() const
Returns the associated measurements.
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Parameters localSegmentPars(const xAOD::MuonSegment &seg)
Returns the localSegPars decoration from a xAODMuon::Segment.
std::pair< Amg::Vector3D, Amg::Vector3D > makeLine(const Parameters &pars)
Returns the parsed parameters into an Eigen line parametrization.
std::string toString(const Parameters &pars)
Dumps the parameters into a string with labels in front of each number.
SegmentAmbiSolver::SegmentVec SegmentVec
STL namespace.
void swap(ElementLinkVector< DOBJ > &lhs, ElementLinkVector< DOBJ > &rhs)
UncalibratedMeasurement_v1 UncalibratedMeasurement
Define the version of the uncalibrated measurement class.
Configuration object to stree the ambiguties.